Периодически производственные (не повторяемые в локальной среде, среде dev или UAT) данные не сохраняются в базе данных, даже если MysqlClient возвращает успех и число строк обновлено.
Сервер приложений для производстваIIS 7 on Windows Server 2008
Этот сервер приложений взаимодействует с 2 отдельными серверами баз данных.
Один на Ubuntu Linux servername 4.15.0-23-generic #25-Ubuntu SMP Wed May 23 18:02:16 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
+-------------------------+----------------------------------+
| Variable_name | Value |
+-------------------------+----------------------------------+
| innodb_version | 5.6.39-83.1 |
| protocol_version | 10 |
| slave_type_conversions | |
| version | 10.1.34-MariaDB-0ubuntu0.18.04.1 |
| version_comment | Ubuntu 18.04 |
| version_compile_machine | x86_64 |
| version_compile_os | debian-linux-gnu |
| version_malloc_library | system jemalloc |
| version_ssl_library | YaSSL 2.4.4 |
| wsrep_patch_version | wsrep_25.23 |
+-------------------------+----------------------------------+
И другой на Fedora Linux servername 4.8.13-100.fc23.x86_64 #1 SMP Fri Dec 9 14:51:40 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
+-------------------------+-----------------+
| Variable_name | Value |
+-------------------------+-----------------+
| innodb_version | 5.6.32-79.0 |
| protocol_version | 10 |
| slave_type_conversions | |
| version | 10.0.28-MariaDB |
| version_comment | MariaDB Server |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
| version_malloc_library | system |
+-------------------------+-----------------+
Хех, пожалуйста, не спрашивайте о совершенно разных серверах баз данных.В любом случае, они оба имеют одинаковые проблемы.
Приложение находится в .NET 4.5
и использует MysqlConnector Mysql.Data dll 6.9.4
для связи с обеими базами данных.
Спорадически (при большой нагрузке (с точки зрения того, чтосистема обычно получает); около 25 одновременно работающих пользователей) система начинает не сохранять изменения в базе данных, даже если приложение возвращается из кода, такого как int x = Sqlcmd.ExecuteNonQuery();
, где x - количество обновленных строк.
Это произойдет с очень простыми обновлениями Mysql, такими как
MySqlConnection conn = new MySqlConnection(TheConnectionString()); conn.Open();
try
{
string Query = "DELETE FROM A_TABLE WHERE USERID = '" + UserID + "'";
MySqlCommand Sqlcmd = new MySqlCommand(Query, conn);
Sqlcmd.CommandText = Query;
Sqlcmd.ExecuteNonQuery();
}
finally { if (conn != null) { conn.Close(); conn.Dispose(); } }
Пожалуйста, не обращайте внимания на явно плохой письменный оператор SQL, который склонен к внедрению SQL.
Другие способы взаимодействия с базой данных (с использованием транзакций) также демонстрируют такое же поведение.
//Create and Instantiate the Connection
sqlConnection = new MySqlConnection(strConnect);
sqlConnection.Open();
//With Transaction
if (bWithTrans == true)
{
sqlTransaction = sqlConnection.BeginTransaction();
//sqlTransaction.IsolationLevel = IsolationLevel.
bRollBack = false; // Reset indicator
}
sqlCommand = new MySqlCommand(qryString, sqlConnection);
sqlCommand.CommandText = qryString;
//With Transaction
if (bWithTrans == true)
{
sqlCommand.Transaction = sqlTransaction;
}
...
...
if (IsInTransaction())
{
if (bRollBack == true)
{
sqlTransaction.Rollback();
}
else
{
sqlTransaction.Commit();
}
sqlTransaction.Connection.Close();
sqlTransaction.Connection.Dispose();
sqlTransaction = null;
}
Я пропустил много кода из вышеперечисленного (например, заключительную часть). Пожалуйста, не обращайте внимания на отсутствие оператора using {}
(я на 99% уверен, что каждое соединение закрыто.)
Во время, когда данные не сохраняются, в select * from information_schema.innodb_trx
*************************** 1. row ***************************
trx_id: 302303150
trx_state: RUNNING
trx_started: 2018-09-27 08:56:45
trx_requested_lock_id: NULL
trx_wait_started: NULL
trx_weight: 0
trx_mysql_thread_id: 117343
trx_query: NULL
trx_operation_state: NULL
trx_tables_in_use: 0
trx_tables_locked: 0
trx_lock_structs: 0
trx_lock_memory_bytes: 360
trx_rows_locked: 0
trx_rows_modified: 0
trx_concurrency_tickets: 0
trx_isolation_level: REPEATABLE READ
trx_unique_checks: 1
trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
trx_adaptive_hash_latched: 0
trx_adaptive_hash_timeout: 10000
trx_is_read_only: 0
trx_autocommit_non_locking: 0
*************************** 1. row ***************************
trx_id: 302303150
trx_state: RUNNING
trx_started: 2018-09-27 08:56:45
trx_requested_lock_id: NULL
trx_wait_started: NULL
trx_weight: 0
trx_mysql_thread_id: 117343
trx_query: NULL
trx_operation_state: NULL
trx_tables_in_use: 0
trx_tables_locked: 0
trx_lock_structs: 0
trx_lock_memory_bytes: 360
trx_rows_locked: 0
trx_rows_modified: 0
trx_concurrency_tickets: 0
trx_isolation_level: REPEATABLE READ
trx_unique_checks: 1
trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
trx_adaptive_hash_latched: 0
trx_adaptive_hash_timeout: 10000
trx_is_read_only: 0
trx_autocommit_non_locking: 0
появляется следующее странное сообщение trx_query: NULL
очень странно видеть ... У меня есть скрипт для печати этоготаблица каждые 0,1 секунды, и она будет отображать ТОЛЬКО trx_query: NULL
, когда данные не сохраняются в базе данных (но сообщают, что это так).
В течение этого времени show engine innodb status
создает это в разделе TRANSACTIONS...
------------
TRANSACTIONS
------------
Trx id counter 147254697
Purge done for trx's n:o < 147254674 undo n:o < 0 state: running but idle
History list length 30
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 222904, OS thread handle 0x7f7a6e08b700, query id 617593737 localhost root init
show engine innodb status
---TRANSACTION 147254688, not started
MySQL thread id 222902, OS thread handle 0x7f7a23a5f700, query id 617593732 10.22.18.39 DB_NAME
---TRANSACTION 147254696, not started
MySQL thread id 222901, OS thread handle 0x7f7a239c9700, query id 617593736 10.22.18.39 DB_NAME
---TRANSACTION 147254644, not started
MySQL thread id 222900, OS thread handle 0x7f7a6e027700, query id 617593526 10.22.18.39 DB_NAME
---TRANSACTION 147254684, not started
MySQL thread id 222897, OS thread handle 0x7f7a6b4e9700, query id 617593709 10.22.18.39 DB_NAME
---TRANSACTION 147240473, not started
MySQL thread id 126445, OS thread handle 0x7f7a23af5700, query id 617593614 10.22.18.41 DB_NAME
---TRANSACTION 84024323, not started
MySQL thread id 1, OS thread handle 0x7f7a6e185700, query id 0 Waiting for background binlog tasks
---TRANSACTION 147254695, ACTIVE 1 sec fetching rows
mysql tables in use 1, locked 0
MySQL thread id 222898, OS thread handle 0x7f7a239fb700, query id 617593734 10.22.18.39 DB_NAME Sending data
SELECT COUNT(*) FROM TABLE I'M HIDING FOR PRIVACY
Trx read view will not see trx with id >= 147254696, sees < 147254696
Trx #rec lock waits 0 #table lock waits 0
Trx total rec lock wait time 0 SEC
Trx total table lock wait time 0 SEC
Я не вижу ничего с точки зрения тупика.
То, что я пробовал ...
- Со времен БДразличаются с точки зрения ОС и версий, мне трудно поверить, что это проблема Mysql (MariaDB).
- Я пытался изменить dll Mysql Connector с 6.9.4 на 6.9.10 и 6.9.12
- Я настроил приложение на перезапуск его пула приложений каждые 1 час в IIS, проблема видна 1 минутуПосле переработки.
- Я закомментировал материал
.beginTransaction()
, так что AUTO-COMMIT по умолчанию выполняется после каждого ExecuteNonQuery()
У кого-нибудь есть какие-нибудь идеи?
Спасибо
** измените здесь журнал запросов, записанный в файл (я отредактировал sql, чтобы удалить имена таблиц / столбцов для конфиденциальности)
245133 Query ROLLBACK
245671 Connect root@localhost as anonymous on
245671 Query select * from information_schema.innodb_trx
244093 Query ROLLBACK
245671 Quit
245133 Init DB DB_NAME
245133 Query SELECT `DESC` as Status FROM TABLE WHERE REC_NUM != 2 ORDER BY `REC_NUM`
245133 Query ROLLBACK
244093 Init DB DB_NAME
244093 Query SELECT COLUMN FROM TABLE WHERE COLUMN IN (SELECT COLUMN FROM TABLE WHERE STATUSCODE = 3) ORDER BY COLUMN
244093 Query ROLLBACK
245133 Init DB DB_NAME
245133 Query SELECT COLUMN FROM TABLE GROUP BY COLUMN ORDER BY COLUMN
245133 Query ROLLBACK
244093 Init DB DB_NAME
244093 Query SELECT COLUMN as Status FROM TABLE WHERE COLUMN <> 1 AND COLUMN <> 2 AND COLUMN <> 4 AND COLUMN <> 10 AND COLUMN <> 11
AND COLUMN <> 12 AND COLUMN <> 13 AND COLUMN <> 15 ORDER BY REC_NUM
244093 Query ROLLBACK
245133 Init DB DB_NAME
245133 Query SELECT COLUMN FROM TABLE WHERE COLUMN = 'DB_NAME'
245133 Query ROLLBACK
245248 Query ROLLBACK
244093 Init DB DB_NAME
245133 Init DB DB_NAME
Сумасшедшийувидеть так много роллбэков ... что может быть причиной этого.В моем комментарии ниже я показываю ROLLBACK в tcpdump в app_server> db_server, поэтому это не БД, инициирующая эти откаты.