embulk-output-mysql 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
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