[
https://issues.apache.org/jira/browse/IGNITE-19247?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Alexander Belyak updated IGNITE-19247:
--------------------------------------
Description:
This is very basic acceptance test.
Code below just create <TABLES> tables with <COLUMNS+1> columns (int key and
varchar cols) and insert <ROWS> rows into each table (with SLEEP ms interval
between operations, with <RETRY> attemps.
{noformat}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TimeoutExceptionReproducer {
private static final String DB_URL = "jdbc:ignite:thin://172.24.1.2:10800";
private static final int COLUMNS = 10;
private static final String TABLE_NAME = "K";
private static final int ROWS = 1000;
private static final int TABLES = 10;
private static final int BATCH_SIZE = 10;
private static final int SLEEP = 30;
private static final int RETRY = 10;
private static String getCreateSql(String tableName) {
StringBuilder sql = new StringBuilder("create table
").append(tableName).append(" (id int primary key");
for (int i = 0; i < COLUMNS; i++) {
sql.append(", col").append(i).append(" varchar NOT NULL");
}
sql.append(")");
return sql.toString();
}
private static final void s() {
if (SLEEP > 0) {
try {
Thread.sleep(SLEEP);
} catch (InterruptedException e) {
// NoOp
}
}
}
private static void createTables(Connection connection, String tableName)
throws SQLException {
try (Statement stmt = connection.createStatement()) {
System.out.println("Creating " + tableName);
stmt.executeUpdate("drop table if exists " + tableName );
s();
stmt.executeUpdate(getCreateSql(tableName));
s();
}
}
private static String getInsertSql(String tableName) {
StringBuilder sql = new StringBuilder("insert into
").append(tableName).append(" values(?");
for (int i = 0; i < COLUMNS; i++) {
sql.append(", ?");
}
sql.append(")");
return sql.toString();
}
private static void insertBatch(PreparedStatement ps) {
int retryCounter = 0;
while(retryCounter <= RETRY) {
try {
ps.executeBatch();
return;
} catch (SQLException e) {
System.err.println(retryCounter + " error while executing " +
ps + ":" + e);
retryCounter++;
}
}
}
private static void insertData(Connection connection, String tableName)
throws SQLException {
long ts = System.currentTimeMillis();
try (PreparedStatement ps =
connection.prepareStatement(getInsertSql(tableName))) {
int batch = 0;
for (int i = 0; i < ROWS; i++) {
ps.setInt(1, i);
for (int j = 2; j < COLUMNS + 2; j++) {
ps.setString(j, "value" + i + "_" + j);
}
ps.addBatch();
batch++;
if (batch == BATCH_SIZE) {
batch = 0;
insertBatch(ps);
ps.clearBatch();
System.out.println("Batch " + BATCH_SIZE + " took " +
(System.currentTimeMillis() - ts) + " to get " + i + " rows");
s();
ts = System.currentTimeMillis();
}
}
if (batch > 0) {
insertBatch(ps);
ps.clearBatch();
s();
}
}
}
private static int testData(Connection connection, String tableName) throws
SQLException {
try (Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("select count(*) from " +
tableName);) {
rs.next();
int count = rs.getInt(1);
int result = ROWS - count;
if (result == 0) {
System.out.println("Found " + count + " rows in " + tableName);
} else {
System.err.println("Found " + count + " rows in " + tableName +
" instead of " + ROWS);
}
s();
return result;
}
}
public static void main(String[] args) throws SQLException {
int lostRows = 0;
try (Connection connection = DriverManager.getConnection(DB_URL)) {
for (int i = 0; i < TABLES; i++) {
String tableName = TABLE_NAME + i;
createTables(connection, tableName);
insertData(connection, tableName);
lostRows += testData(connection, tableName);
}
}
System.exit(lostRows);
}
}
{noformat}
And we can see some problems, like:
1) Replication timeout exception
2) Data loss
even if there are only one node in the cluster, small number of columns, tables
and rows and huge sleep between operations.
was:
{color:#0033b3}import {color}{color:#000000}java.sql.Connection{color};
{color:#0033b3}import {color}{color:#000000}java.sql.DriverManager{color};
{color:#0033b3}import {color}{color:#000000}java.sql.PreparedStatement{color};
{color:#0033b3}import {color}{color:#000000}java.sql.ResultSet{color};
{color:#0033b3}import {color}{color:#000000}java.sql.SQLException{color};
{color:#0033b3}import {color}{color:#000000}java.sql.Statement{color};
{color:#0033b3}public class {color}{color:#000000}TimeoutExceptionReproducer
{color}{
{color:#0033b3}private static final {color}{color:#000000}String
{color}{color:#871094}DB_URL {color}=
{color:#067d17}"jdbc:ignite:thin://172.24.1.2:10800"{color};
{color:#0033b3}private static final int {color}{color:#871094}COLUMNS {color}=
{color:#1750eb}10{color};
{color:#0033b3}private static final {color}{color:#000000}String
{color}{color:#871094}TABLE_NAME {color}= {color:#067d17}"K"{color};
{color:#0033b3}private static final int {color}{color:#871094}ROWS {color}=
{color:#1750eb}1000{color};
{color:#0033b3}private static final int {color}{color:#871094}TABLES {color}=
{color:#1750eb}10{color};
{color:#0033b3}private static final int {color}{color:#871094}BATCH_SIZE
{color}= {color:#1750eb}10{color};
{color:#0033b3}private static final int {color}{color:#871094}SLEEP {color}=
{color:#1750eb}30{color};
{color:#0033b3}private static final int {color}{color:#871094}RETRY {color}=
{color:#1750eb}10{color};
{color:#0033b3}private static {color}{color:#000000}String
{color}{color:#00627a}getCreateSql{color}({color:#000000}String
{color}tableName) {
{color:#000000}StringBuilder sql {color}= {color:#0033b3}new
{color}StringBuilder({color:#067d17}"create table
"{color}).append(tableName).append({color:#067d17}" (id int primary
key"{color});
{color:#0033b3}for {color}({color:#0033b3}int {color}i =
{color:#1750eb}0{color}; i < {color:#871094}COLUMNS{color}; i++) {
{color:#000000}sql{color}.append({color:#067d17}",
col"{color}).append(i).append({color:#067d17}" varchar NOT NULL"{color});
}
{color:#000000}sql{color}.append({color:#067d17}")"{color});
{color:#0033b3}return {color}{color:#000000}sql{color}.toString();
}
{color:#0033b3}private static final void {color}{color:#00627a}s{color}() {
{color:#0033b3}if {color}({color:#871094}SLEEP {color}>
{color:#1750eb}0{color}) {
{color:#0033b3}try {color}{
{color:#000000}Thread{color}.sleep({color:#871094}SLEEP{color});
} {color:#0033b3}catch {color}({color:#000000}InterruptedException {color}e) {
{color:#8c8c8c}// NoOp
{color}{color:#8c8c8c} {color}}
}
}
{color:#0033b3}private static void
{color}{color:#00627a}createTables{color}({color:#000000}Connection
{color}connection, {color:#000000}String {color}tableName)
{color:#0033b3}throws {color}{color:#000000}SQLException {color}{
{color:#0033b3}try {color}({color:#000000}Statement stmt {color}=
connection.createStatement()) {
{color:#000000}System{color}.{color:#871094}out{color}.println({color:#067d17}"Creating
" {color}+ tableName);
{color:#000000}stmt{color}.executeUpdate({color:#067d17}"{color}{color:#067d17}drop
table if exists {color}{color:#067d17}" {color}+ tableName );
s();
{color:#000000}stmt{color}.executeUpdate(getCreateSql(tableName));
s();
}
}
{color:#0033b3}private static {color}{color:#000000}String
{color}{color:#00627a}getInsertSql{color}({color:#000000}String
{color}tableName) {
{color:#000000}StringBuilder sql {color}= {color:#0033b3}new
{color}StringBuilder({color:#067d17}"insert into
"{color}).append(tableName).append({color:#067d17}" values(?"{color});
{color:#0033b3}for {color}({color:#0033b3}int {color}i =
{color:#1750eb}0{color}; i < {color:#871094}COLUMNS{color}; i++) {
{color:#000000}sql{color}.append({color:#067d17}", ?"{color});
}
{color:#000000}sql{color}.append({color:#067d17}")"{color});
{color:#0033b3}return {color}{color:#000000}sql{color}.toString();
}
{color:#0033b3}private static void
{color}{color:#00627a}insertBatch{color}({color:#000000}PreparedStatement
{color}ps) {
{color:#0033b3}int {color}retryCounter = {color:#1750eb}0{color};
{color:#0033b3}while{color}(retryCounter <= {color:#871094}RETRY{color}) {
{color:#0033b3}try {color}{
ps.executeBatch();
{color:#0033b3}return{color};
} {color:#0033b3}catch {color}({color:#000000}SQLException {color}e) {
{color:#000000}System{color}.{color:#871094}err{color}.println(retryCounter +
{color:#067d17}" error while executing " {color}+ ps + {color:#067d17}":"
{color}+ e);
retryCounter++;
}
}
}
{color:#0033b3}private static void
{color}{color:#00627a}insertData{color}({color:#000000}Connection
{color}connection, {color:#000000}String {color}tableName)
{color:#0033b3}throws {color}{color:#000000}SQLException {color}{
{color:#0033b3}long {color}ts =
{color:#000000}System{color}.currentTimeMillis();
{color:#0033b3}try {color}({color:#000000}PreparedStatement ps {color}=
connection.prepareStatement(getInsertSql(tableName))) {
{color:#0033b3}int {color}batch = {color:#1750eb}0{color};
{color:#0033b3}for {color}({color:#0033b3}int {color}i =
{color:#1750eb}0{color}; i < {color:#871094}ROWS{color}; i++) {
{color:#000000}ps{color}.setInt({color:#1750eb}1{color}, i);
{color:#0033b3}for {color}({color:#0033b3}int {color}j =
{color:#1750eb}2{color}; j < {color:#871094}COLUMNS {color}+
{color:#1750eb}2{color}; j++) {
{color:#000000}ps{color}.setString(j, {color:#067d17}"value" {color}+ i +
{color:#067d17}"_" {color}+ j);
}
{color:#000000}ps{color}.addBatch();
batch++;
{color:#0033b3}if {color}(batch == {color:#871094}BATCH_SIZE{color}) {
batch = {color:#1750eb}0{color};
insertBatch({color:#000000}ps{color});
{color:#000000}ps{color}.clearBatch();
{color:#000000}System{color}.{color:#871094}out{color}.println({color:#067d17}"Batch
" {color}+ {color:#871094}BATCH_SIZE {color}+ {color:#067d17}" took " {color}+
({color:#000000}System{color}.currentTimeMillis() - ts) + {color:#067d17}" to
get " {color}+ i + {color:#067d17}" rows"{color});
s();
ts = {color:#000000}System{color}.currentTimeMillis();
}
}
{color:#0033b3}if {color}(batch > {color:#1750eb}0{color}) {
insertBatch({color:#000000}ps{color});
{color:#000000}ps{color}.clearBatch();
s();
}
}
}
{color:#0033b3}private static int
{color}{color:#00627a}testData{color}({color:#000000}Connection
{color}connection, {color:#000000}String {color}tableName)
{color:#0033b3}throws {color}{color:#000000}SQLException {color}{
{color:#0033b3}try {color}({color:#000000}Statement stmt {color}=
connection.createStatement();
{color:#000000}ResultSet rs {color}=
{color:#000000}stmt{color}.executeQuery({color:#067d17}"{color}{color:#067d17}select
count(*) from {color}{color:#067d17}" {color}+ tableName);) {
{color:#000000}rs{color}.next();
{color:#0033b3}int {color}{color:#000000}count {color}=
{color:#000000}rs{color}.getInt({color:#1750eb}1{color});
{color:#0033b3}int {color}{color:#000000}result {color}= {color:#871094}ROWS
{color}- {color:#000000}count{color};
{color:#0033b3}if {color}({color:#000000}result {color}==
{color:#1750eb}0{color}) {
{color:#000000}System{color}.{color:#871094}out{color}.println({color:#067d17}"Found
" {color}+ {color:#000000}count {color}+ {color:#067d17}" rows in " {color}+
tableName);
} {color:#0033b3}else {color}{
{color:#000000}System{color}.{color:#871094}err{color}.println({color:#067d17}"Found
" {color}+ {color:#000000}count {color}+ {color:#067d17}" rows in " {color}+
tableName + {color:#067d17}" instead of " {color}+ {color:#871094}ROWS{color});
}
s();
{color:#0033b3}return {color}{color:#000000}result{color};
}
}
{color:#0033b3}public static void
{color}{color:#00627a}main{color}({color:#000000}String{color}[] args)
{color:#0033b3}throws {color}{color:#000000}SQLException {color}{
{color:#0033b3}int {color}lostRows = {color:#1750eb}0{color};
{color:#0033b3}try {color}({color:#000000}Connection connection {color}=
{color:#000000}DriverManager{color}.getConnection({color:#871094}DB_URL{color}))
{
{color:#0033b3}for {color}({color:#0033b3}int {color}i =
{color:#1750eb}0{color}; i < {color:#871094}TABLES{color}; i++) {
{color:#000000}String tableName {color}= {color:#871094}TABLE_NAME {color}+ i;
createTables({color:#000000}connection{color}, {color:#000000}tableName{color});
insertData({color:#000000}connection{color}, {color:#000000}tableName{color});
lostRows += testData({color:#000000}connection{color},
{color:#000000}tableName{color});
}
}
{color:#000000}System{color}.exit(lostRows);
}
}
> Replication is timed out
> ------------------------
>
> Key: IGNITE-19247
> URL: https://issues.apache.org/jira/browse/IGNITE-19247
> Project: Ignite
> Issue Type: Bug
> Components: general
> Affects Versions: 3.0
> Reporter: Alexander Belyak
> Priority: Critical
> Labels: ignite-3
> Fix For: 3.0
>
>
> This is very basic acceptance test.
> Code below just create <TABLES> tables with <COLUMNS+1> columns (int key and
> varchar cols) and insert <ROWS> rows into each table (with SLEEP ms interval
> between operations, with <RETRY> attemps.
>
> {noformat}
> import java.sql.Connection;
> import java.sql.DriverManager;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> import java.sql.SQLException;
> import java.sql.Statement;
> public class TimeoutExceptionReproducer {
> private static final String DB_URL =
> "jdbc:ignite:thin://172.24.1.2:10800";
> private static final int COLUMNS = 10;
> private static final String TABLE_NAME = "K";
> private static final int ROWS = 1000;
> private static final int TABLES = 10;
> private static final int BATCH_SIZE = 10;
> private static final int SLEEP = 30;
> private static final int RETRY = 10;
> private static String getCreateSql(String tableName) {
> StringBuilder sql = new StringBuilder("create table
> ").append(tableName).append(" (id int primary key");
> for (int i = 0; i < COLUMNS; i++) {
> sql.append(", col").append(i).append(" varchar NOT NULL");
> }
> sql.append(")");
> return sql.toString();
> }
> private static final void s() {
> if (SLEEP > 0) {
> try {
> Thread.sleep(SLEEP);
> } catch (InterruptedException e) {
> // NoOp
> }
> }
> }
> private static void createTables(Connection connection, String tableName)
> throws SQLException {
> try (Statement stmt = connection.createStatement()) {
> System.out.println("Creating " + tableName);
> stmt.executeUpdate("drop table if exists " + tableName );
> s();
> stmt.executeUpdate(getCreateSql(tableName));
> s();
> }
> }
> private static String getInsertSql(String tableName) {
> StringBuilder sql = new StringBuilder("insert into
> ").append(tableName).append(" values(?");
> for (int i = 0; i < COLUMNS; i++) {
> sql.append(", ?");
> }
> sql.append(")");
> return sql.toString();
> }
> private static void insertBatch(PreparedStatement ps) {
> int retryCounter = 0;
> while(retryCounter <= RETRY) {
> try {
> ps.executeBatch();
> return;
> } catch (SQLException e) {
> System.err.println(retryCounter + " error while executing " +
> ps + ":" + e);
> retryCounter++;
> }
> }
> }
> private static void insertData(Connection connection, String tableName)
> throws SQLException {
> long ts = System.currentTimeMillis();
> try (PreparedStatement ps =
> connection.prepareStatement(getInsertSql(tableName))) {
> int batch = 0;
> for (int i = 0; i < ROWS; i++) {
> ps.setInt(1, i);
> for (int j = 2; j < COLUMNS + 2; j++) {
> ps.setString(j, "value" + i + "_" + j);
> }
> ps.addBatch();
> batch++;
> if (batch == BATCH_SIZE) {
> batch = 0;
> insertBatch(ps);
> ps.clearBatch();
> System.out.println("Batch " + BATCH_SIZE + " took " +
> (System.currentTimeMillis() - ts) + " to get " + i + " rows");
> s();
> ts = System.currentTimeMillis();
> }
> }
> if (batch > 0) {
> insertBatch(ps);
> ps.clearBatch();
> s();
> }
> }
> }
> private static int testData(Connection connection, String tableName)
> throws SQLException {
> try (Statement stmt = connection.createStatement();
> ResultSet rs = stmt.executeQuery("select count(*) from " +
> tableName);) {
> rs.next();
> int count = rs.getInt(1);
> int result = ROWS - count;
> if (result == 0) {
> System.out.println("Found " + count + " rows in " +
> tableName);
> } else {
> System.err.println("Found " + count + " rows in " + tableName
> + " instead of " + ROWS);
> }
> s();
> return result;
> }
> }
> public static void main(String[] args) throws SQLException {
> int lostRows = 0;
> try (Connection connection = DriverManager.getConnection(DB_URL)) {
> for (int i = 0; i < TABLES; i++) {
> String tableName = TABLE_NAME + i;
> createTables(connection, tableName);
> insertData(connection, tableName);
> lostRows += testData(connection, tableName);
> }
> }
> System.exit(lostRows);
> }
> }
> {noformat}
> And we can see some problems, like:
> 1) Replication timeout exception
> 2) Data loss
> even if there are only one node in the cluster, small number of columns,
> tables and rows and huge sleep between operations.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)