embulk-output-mysql 0.8.2 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec057792c6f84dbf9922a6d449e42224b83821c8
4
- data.tar.gz: 511c6a404700f429ad9601aad2acb877b275843e
3
+ metadata.gz: 753cd35ceccb305741025c9f2956e2a8bcd43e0f
4
+ data.tar.gz: a264b7fe51085f24b4a96bfe3f98defc45f3ba4f
5
5
  SHA512:
6
- metadata.gz: a71c7ef498318bc1857c4845e4826d5d33208cee89a7cfb16f991f5a3748351c3bf84bee0d59fc8b791e93031ba3b4a38727f7d8aad7be5098cc43acdc5c7747
7
- data.tar.gz: 58e96c01b69b017fe1f5ab1765e75d799ba90af2a6ec0703e775e52f038760dd793ea14950533ce36b0b269ea86ee1e8b5546550b91a27411cd0daa08c21a3b4
6
+ metadata.gz: e3af007fe65e593ab4ec3740a3a399d9c622e6867af811c2774445744ebe0a972eddc7610c692793a81a8b9eab7e086bc444ef796fb1022c1e686a3ff1ad5343
7
+ data.tar.gz: 9e59a1bf4698cca86fc4389c66e84b6a4ad17cc778fc4c72fd55f43377120479fc369f2d91e3247867d00b2f62578624abd368dafa34495c432c01a94e1250b6
data/README.md CHANGED
@@ -21,8 +21,9 @@ MySQL output plugin for Embulk loads records to MySQL.
21
21
  - **table**: destination table name (string, required)
22
22
  - **create_table_constraint**: table constraint added to `CREATE TABLE` statement, like `CREATE TABLE <table_name> (<column1> <type1>, <column2> <type2>, ..., <create_table_constraint>) <create_table_option>`.
23
23
  - **create_table_option**: table option added to `CREATE TABLE` statement, like `CREATE TABLE <table_name> (<column1> <type1>, <column2> <type2>, ..., <create_table_constraint>) <create_table_option>`.
24
+ - **transaction_isolation**: transaction isolation level for each connection ("read_uncommitted", "read_committed", "repeatable_read" or "serializable"). if not specified, database default value will be used.
24
25
  - **options**: extra connection properties (hash, default: {})
25
- - **retry_limit**: max retry count for database operations (integer, default: 12)
26
+ - **retry_limit**: max retry count for database operations (integer, default: 12). When intermediate table to create already created by another process, this plugin will retry with another table name to avoid collision. And, when a deadlock occurs in loading records, this plugin will retry loading after the transaction rolled back.
26
27
  - **retry_wait**: initial retry wait time in milliseconds (integer, default: 1000 (1 second))
27
28
  - **max_retry_wait**: upper limit of retry wait, which will be doubled at every retry (integer, default: 1800000 (30 minutes))
28
29
  - **mode**: "insert", "insert_direct", "truncate_insert", "merge", "merge_direct", or "replace". See below. (string, required)
@@ -12,6 +12,7 @@ import org.embulk.output.jdbc.AbstractJdbcOutputPlugin;
12
12
  import org.embulk.output.jdbc.Ssl;
13
13
  import org.embulk.output.jdbc.BatchInsert;
14
14
  import org.embulk.output.jdbc.JdbcOutputConnection;
15
+ import org.embulk.output.jdbc.JdbcOutputConnector;
15
16
  import org.embulk.output.jdbc.MergeConfig;
16
17
  import org.embulk.output.jdbc.TableIdentifier;
17
18
  import org.embulk.output.mysql.MySQLOutputConnection;
@@ -71,7 +72,7 @@ public class MySQLOutputPlugin
71
72
  }
72
73
 
73
74
  @Override
74
- protected MySQLOutputConnector getConnector(PluginTask task, boolean retryableMetadataOperation)
75
+ protected JdbcOutputConnector getConnector(PluginTask task, boolean retryableMetadataOperation)
75
76
  {
76
77
  MySQLPluginTask t = (MySQLPluginTask) task;
77
78
 
@@ -122,7 +123,7 @@ public class MySQLOutputPlugin
122
123
  props.setProperty("password", t.getPassword());
123
124
  logConnectionProperties(url, props);
124
125
 
125
- return new MySQLOutputConnector(url, props);
126
+ return new MySQLOutputConnector(url, props, task.getTransactionIsolation());
126
127
  }
127
128
 
128
129
  @Override
@@ -1,17 +1,17 @@
1
1
  package org.embulk.output.mysql;
2
2
 
3
- import java.util.List;
4
3
  import java.io.IOException;
5
4
  import java.sql.Types;
6
5
  import java.sql.SQLException;
7
6
  import com.google.common.base.Optional;
7
+ import org.embulk.output.jdbc.JdbcOutputConnector;
8
8
  import org.embulk.output.jdbc.MergeConfig;
9
9
  import org.embulk.output.jdbc.StandardBatchInsert;
10
10
 
11
11
  public class MySQLBatchInsert
12
12
  extends StandardBatchInsert
13
13
  {
14
- public MySQLBatchInsert(MySQLOutputConnector connector, Optional<MergeConfig> mergeConfig) throws IOException, SQLException
14
+ public MySQLBatchInsert(JdbcOutputConnector connector, Optional<MergeConfig> mergeConfig) throws IOException, SQLException
15
15
  {
16
16
  super(connector, mergeConfig);
17
17
  }
@@ -14,11 +14,10 @@ import org.embulk.output.jdbc.TableIdentifier;
14
14
  public class MySQLOutputConnection
15
15
  extends JdbcOutputConnection
16
16
  {
17
- public MySQLOutputConnection(Connection connection, boolean autoCommit)
17
+ public MySQLOutputConnection(Connection connection)
18
18
  throws SQLException
19
19
  {
20
20
  super(connection, null);
21
- connection.setAutoCommit(autoCommit);
22
21
  }
23
22
 
24
23
  @Override
@@ -5,26 +5,32 @@ import java.sql.Connection;
5
5
  import java.sql.DriverManager;
6
6
  import java.sql.SQLException;
7
7
 
8
- import org.embulk.output.jdbc.JdbcOutputConnector;
8
+ import org.embulk.output.jdbc.JdbcOutputConnection;
9
+ import org.embulk.output.jdbc.AbstractJdbcOutputConnector;
10
+ import org.embulk.output.jdbc.TransactionIsolation;
11
+
12
+ import com.google.common.base.Optional;
9
13
 
10
14
  public class MySQLOutputConnector
11
- implements JdbcOutputConnector
15
+ extends AbstractJdbcOutputConnector
12
16
  {
13
17
  private final String url;
14
18
  private final Properties properties;
15
19
 
16
- public MySQLOutputConnector(String url, Properties properties)
20
+ public MySQLOutputConnector(String url, Properties properties,
21
+ Optional<TransactionIsolation> transactionIsolation)
17
22
  {
23
+ super(transactionIsolation);
18
24
  this.url = url;
19
25
  this.properties = properties;
20
26
  }
21
27
 
22
28
  @Override
23
- public MySQLOutputConnection connect(boolean autoCommit) throws SQLException
29
+ protected JdbcOutputConnection connect() throws SQLException
24
30
  {
25
31
  Connection c = DriverManager.getConnection(url, properties);
26
32
  try {
27
- MySQLOutputConnection con = new MySQLOutputConnection(c, autoCommit);
33
+ MySQLOutputConnection con = new MySQLOutputConnection(c);
28
34
  c = null;
29
35
  return con;
30
36
  } finally {
@@ -6,6 +6,9 @@ import static org.embulk.test.EmbulkTests.readSortedFile;
6
6
  import java.io.IOException;
7
7
  import java.nio.file.Files;
8
8
  import java.nio.file.Path;
9
+ import java.sql.Connection;
10
+ import java.sql.DriverManager;
11
+ import java.sql.SQLException;
9
12
 
10
13
  import org.embulk.config.ConfigSource;
11
14
  import org.embulk.test.EmbulkTests;
@@ -22,6 +25,17 @@ public class MySQLTests
22
25
  return EmbulkTests.config("EMBULK_OUTPUT_MYSQL_TEST_CONFIG");
23
26
  }
24
27
 
28
+ public static Connection connect() throws SQLException
29
+ {
30
+ ConfigSource config = baseConfig();
31
+
32
+ String url = String.format("jdbc:mysql://%s:%s/%s",
33
+ config.get(String.class, "host"),
34
+ config.get(String.class, "port", "3306"),
35
+ config.get(String.class, "database"));
36
+ return DriverManager.getConnection(url, config.get(String.class, "user"), config.get(String.class, "password"));
37
+ }
38
+
25
39
  public static void execute(String sql)
26
40
  {
27
41
  ConfigSource config = baseConfig();
@@ -0,0 +1,139 @@
1
+ package org.embulk.output.mysql;
2
+
3
+ import static org.embulk.output.mysql.MySQLTests.execute;
4
+ import static org.embulk.output.mysql.MySQLTests.selectRecords;
5
+ import static org.hamcrest.Matchers.is;
6
+ import static org.junit.Assert.assertThat;
7
+
8
+ import java.io.File;
9
+ import java.net.URISyntaxException;
10
+ import java.net.URL;
11
+ import java.nio.file.FileSystems;
12
+ import java.nio.file.Path;
13
+ import java.sql.Connection;
14
+ import java.sql.Statement;
15
+
16
+ import org.embulk.config.ConfigDiff;
17
+ import org.embulk.config.ConfigSource;
18
+ import org.embulk.output.MySQLOutputPlugin;
19
+ import org.embulk.spi.OutputPlugin;
20
+ import org.embulk.test.EmbulkTests;
21
+ import org.embulk.test.TestingEmbulk;
22
+ import org.junit.Before;
23
+ import org.junit.Rule;
24
+ import org.junit.Test;
25
+
26
+ import com.google.common.io.Resources;
27
+
28
+ public class RetryTest
29
+ {
30
+ private static final String BASIC_RESOURCE_PATH = "org/embulk/output/mysql/test/expect/retry/";
31
+
32
+ private static ConfigSource loadYamlResource(TestingEmbulk embulk, String fileName)
33
+ {
34
+ return embulk.loadYamlResource(BASIC_RESOURCE_PATH + fileName);
35
+ }
36
+
37
+ private static String readResource(String fileName)
38
+ {
39
+ return EmbulkTests.readResource(BASIC_RESOURCE_PATH + fileName);
40
+ }
41
+
42
+ @Rule
43
+ public TestingEmbulk embulk = TestingEmbulk.builder()
44
+ .registerPlugin(OutputPlugin.class, "mysql", MySQLOutputPlugin.class)
45
+ .build();
46
+
47
+ private ConfigSource baseConfig;
48
+
49
+ @Before
50
+ public void setup()
51
+ {
52
+ baseConfig = MySQLTests.baseConfig();
53
+ execute(readResource("setup.sql")); // setup rows
54
+ }
55
+
56
+ @Test
57
+ public void testSucceeded() throws Exception
58
+ {
59
+ Path in1 = toPath("test1.csv");
60
+ TestingEmbulk.RunResult result1 = embulk.runOutput(baseConfig.merge(loadYamlResource(embulk, "test1.yml")), in1);
61
+ assertThat(selectRecords(embulk, "test1"), is(readResource("test1_expected.csv")));
62
+ }
63
+
64
+ @Test
65
+ public void testRetry() throws Exception
66
+ {
67
+ Thread thread = new Thread() {
68
+ @Override
69
+ public void run() {
70
+ try {
71
+ try (Connection conn = MySQLTests.connect()) {
72
+ conn.setAutoCommit(false);
73
+ try (Statement statement = conn.createStatement()) {
74
+ // make the transaction larger so that embulk-output-mysql transaction will be rolled back at a deadlock.
75
+ for (int i = 100; i < 110; i++) {
76
+ statement.execute("insert into test1 values('B" + i + "', 0)");
77
+ }
78
+
79
+ statement.execute("insert into test1 values('A003', 0)");
80
+ Thread.sleep(3000);
81
+ // deadlock will occur
82
+ statement.execute("insert into test1 values('A002', 0)");
83
+ conn.rollback();
84
+ }
85
+ }
86
+ } catch (Exception e) {
87
+ e.printStackTrace();
88
+ }
89
+ }
90
+ };
91
+ thread.start();
92
+
93
+ Path in1 = toPath("test1.csv");
94
+ TestingEmbulk.RunResult result1 = embulk.runOutput(baseConfig.merge(loadYamlResource(embulk, "test1.yml")), in1);
95
+ assertThat(selectRecords(embulk, "test1"), is(readResource("test1_expected.csv")));
96
+ }
97
+
98
+ // will be flushed multiple times
99
+ @Test
100
+ public void testRetryLarge() throws Exception
101
+ {
102
+ Thread thread = new Thread() {
103
+ @Override
104
+ public void run() {
105
+ try {
106
+ try (Connection conn = MySQLTests.connect()) {
107
+ conn.setAutoCommit(false);
108
+ try (Statement statement = conn.createStatement()) {
109
+ // make the transaction larger so that embulk-output-mysql transaction will be rolled back at a deadlock.
110
+ for (int i = 100; i < 200; i++) {
111
+ statement.execute("insert into test1 values('B" + i + "', 0)");
112
+ }
113
+
114
+ statement.execute("insert into test1 values('A170', 0)");
115
+ Thread.sleep(3000);
116
+ // deadlock will occur
117
+ statement.execute("insert into test1 values('A160', 0)");
118
+ conn.rollback();
119
+ }
120
+ }
121
+ } catch (Exception e) {
122
+ e.printStackTrace();
123
+ }
124
+ }
125
+ };
126
+ thread.start();
127
+
128
+ Path in1 = toPath("test1_large.csv");
129
+ TestingEmbulk.RunResult result1 = embulk.runOutput(baseConfig.merge(loadYamlResource(embulk, "test1_large.yml")), in1);
130
+ assertThat(selectRecords(embulk, "test1"), is(readResource("test1_large_expected.csv")));
131
+ }
132
+
133
+ private Path toPath(String fileName) throws URISyntaxException
134
+ {
135
+ URL url = Resources.getResource(BASIC_RESOURCE_PATH + fileName);
136
+ return FileSystems.getDefault().getPath(new File(url.toURI()).getAbsolutePath());
137
+ }
138
+
139
+ }
@@ -0,0 +1,7 @@
1
+ drop table if exists test1;
2
+
3
+ create table test1 (
4
+ id char(4),
5
+ num int,
6
+ primary key (id)
7
+ );
@@ -0,0 +1,5 @@
1
+ id:string,num:long
2
+ A001,11
3
+ A002,22
4
+ A003,33
5
+ A004,44
@@ -0,0 +1,2 @@
1
+ table: test1
2
+ mode: insert_direct
@@ -0,0 +1,4 @@
1
+ A001,11
2
+ A002,22
3
+ A003,33
4
+ A004,44
@@ -0,0 +1,101 @@
1
+ id:string,num:long
2
+ A100,100
3
+ A101,101
4
+ A102,102
5
+ A103,103
6
+ A104,104
7
+ A105,105
8
+ A106,106
9
+ A107,107
10
+ A108,108
11
+ A109,109
12
+ A110,110
13
+ A111,111
14
+ A112,112
15
+ A113,113
16
+ A114,114
17
+ A115,115
18
+ A116,116
19
+ A117,117
20
+ A118,118
21
+ A119,119
22
+ A120,120
23
+ A121,121
24
+ A122,122
25
+ A123,123
26
+ A124,124
27
+ A125,125
28
+ A126,126
29
+ A127,127
30
+ A128,128
31
+ A129,129
32
+ A130,130
33
+ A131,131
34
+ A132,132
35
+ A133,133
36
+ A134,134
37
+ A135,135
38
+ A136,136
39
+ A137,137
40
+ A138,138
41
+ A139,139
42
+ A140,140
43
+ A141,141
44
+ A142,142
45
+ A143,143
46
+ A144,144
47
+ A145,145
48
+ A146,146
49
+ A147,147
50
+ A148,148
51
+ A149,149
52
+ A150,150
53
+ A151,151
54
+ A152,152
55
+ A153,153
56
+ A154,154
57
+ A155,155
58
+ A156,156
59
+ A157,157
60
+ A158,158
61
+ A159,159
62
+ A160,160
63
+ A161,161
64
+ A162,162
65
+ A163,163
66
+ A164,164
67
+ A165,165
68
+ A166,166
69
+ A167,167
70
+ A168,168
71
+ A169,169
72
+ A170,170
73
+ A171,171
74
+ A172,172
75
+ A173,173
76
+ A174,174
77
+ A175,175
78
+ A176,176
79
+ A177,177
80
+ A178,178
81
+ A179,179
82
+ A180,180
83
+ A181,181
84
+ A182,182
85
+ A183,183
86
+ A184,184
87
+ A185,185
88
+ A186,186
89
+ A187,187
90
+ A188,188
91
+ A189,189
92
+ A190,190
93
+ A191,191
94
+ A192,192
95
+ A193,193
96
+ A194,194
97
+ A195,195
98
+ A196,196
99
+ A197,197
100
+ A198,198
101
+ A199,199
@@ -0,0 +1,3 @@
1
+ table: test1
2
+ mode: insert_direct
3
+ batch_size: 1000
@@ -0,0 +1,100 @@
1
+ A100,100
2
+ A101,101
3
+ A102,102
4
+ A103,103
5
+ A104,104
6
+ A105,105
7
+ A106,106
8
+ A107,107
9
+ A108,108
10
+ A109,109
11
+ A110,110
12
+ A111,111
13
+ A112,112
14
+ A113,113
15
+ A114,114
16
+ A115,115
17
+ A116,116
18
+ A117,117
19
+ A118,118
20
+ A119,119
21
+ A120,120
22
+ A121,121
23
+ A122,122
24
+ A123,123
25
+ A124,124
26
+ A125,125
27
+ A126,126
28
+ A127,127
29
+ A128,128
30
+ A129,129
31
+ A130,130
32
+ A131,131
33
+ A132,132
34
+ A133,133
35
+ A134,134
36
+ A135,135
37
+ A136,136
38
+ A137,137
39
+ A138,138
40
+ A139,139
41
+ A140,140
42
+ A141,141
43
+ A142,142
44
+ A143,143
45
+ A144,144
46
+ A145,145
47
+ A146,146
48
+ A147,147
49
+ A148,148
50
+ A149,149
51
+ A150,150
52
+ A151,151
53
+ A152,152
54
+ A153,153
55
+ A154,154
56
+ A155,155
57
+ A156,156
58
+ A157,157
59
+ A158,158
60
+ A159,159
61
+ A160,160
62
+ A161,161
63
+ A162,162
64
+ A163,163
65
+ A164,164
66
+ A165,165
67
+ A166,166
68
+ A167,167
69
+ A168,168
70
+ A169,169
71
+ A170,170
72
+ A171,171
73
+ A172,172
74
+ A173,173
75
+ A174,174
76
+ A175,175
77
+ A176,176
78
+ A177,177
79
+ A178,178
80
+ A179,179
81
+ A180,180
82
+ A181,181
83
+ A182,182
84
+ A183,183
85
+ A184,184
86
+ A185,185
87
+ A186,186
88
+ A187,187
89
+ A188,188
90
+ A189,189
91
+ A190,190
92
+ A191,191
93
+ A192,192
94
+ A193,193
95
+ A194,194
96
+ A195,195
97
+ A196,196
98
+ A197,197
99
+ A198,198
100
+ A199,199
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-output-mysql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-30 00:00:00.000000000 Z
11
+ date: 2019-05-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Inserts or updates records to a table.
14
14
  email:
@@ -19,8 +19,8 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - README.md
21
21
  - build.gradle
22
- - classpath/embulk-output-jdbc-0.8.2.jar
23
- - classpath/embulk-output-mysql-0.8.2.jar
22
+ - classpath/embulk-output-jdbc-0.8.3.jar
23
+ - classpath/embulk-output-mysql-0.8.3.jar
24
24
  - default_jdbc_driver/mysql-connector-java-5.1.44.jar
25
25
  - lib/embulk/output/mysql.rb
26
26
  - src/main/java/org/embulk/output/MySQLOutputPlugin.java
@@ -32,6 +32,7 @@ files:
32
32
  - src/test/java/org/embulk/output/mysql/BeforeLoadTest.java
33
33
  - src/test/java/org/embulk/output/mysql/CreateTableTest.java
34
34
  - src/test/java/org/embulk/output/mysql/MySQLTests.java
35
+ - src/test/java/org/embulk/output/mysql/RetryTest.java
35
36
  - src/test/resources/org/embulk/output/mysql/test/expect/after_load/setup.sql
36
37
  - src/test/resources/org/embulk/output/mysql/test/expect/after_load/test1.csv
37
38
  - src/test/resources/org/embulk/output/mysql/test/expect/after_load/test_expected.diff
@@ -62,6 +63,13 @@ files:
62
63
  - src/test/resources/org/embulk/output/mysql/test/expect/create_table/test_table_constraint_expected.csv
63
64
  - src/test/resources/org/embulk/output/mysql/test/expect/create_table/test_table_option.yml
64
65
  - src/test/resources/org/embulk/output/mysql/test/expect/create_table/test_table_option_expected.csv
66
+ - src/test/resources/org/embulk/output/mysql/test/expect/retry/setup.sql
67
+ - src/test/resources/org/embulk/output/mysql/test/expect/retry/test1.csv
68
+ - src/test/resources/org/embulk/output/mysql/test/expect/retry/test1.yml
69
+ - src/test/resources/org/embulk/output/mysql/test/expect/retry/test1_expected.csv
70
+ - src/test/resources/org/embulk/output/mysql/test/expect/retry/test1_large.csv
71
+ - src/test/resources/org/embulk/output/mysql/test/expect/retry/test1_large.yml
72
+ - src/test/resources/org/embulk/output/mysql/test/expect/retry/test1_large_expected.csv
65
73
  homepage: https://github.com/embulk/embulk-output-jdbc
66
74
  licenses:
67
75
  - Apache 2.0
Binary file