Không thấy dữ liệu cam kết của MySQL để chọn truy vấn


13

Bối cảnh: Khung được sử dụng là Spring và tất cả các truy vấn được chạy với JdbcTemplate. Phiên bản máy chủ Mysql là 5.6.19. Đây tablelà một InnoDB tablevà mặc định như auto commitvà mức cô lập lặp lại-đọc được đặt.

Vấn đề : Xảy Insertra bên trong một giao dịch và một selectdữ liệu đọc cùng một dữ liệu được chèn không nhìn thấy dữ liệu. Các selectchạy sau sự insertvà sau khi insertgiao dịch có commited.

Tôi đã kích hoạt nhật ký bin cũng như nhật ký chung trong mysql. Nhật ký liên quan dưới đây

nhật ký bin:

SET TIMESTAMP=1438265764/*!*/;
BEGIN
/*!*/;
# at 249935389
#150730 14:16:04 server id 1  end_log_pos 249935606 CRC32 0xa6aca292    Query   thread_id=40    exec_time=0     error_code=0
SET TIMESTAMP=1438265764/*!*/;
insert into user_geo_loc_latest(user_id, lat, lng) values(x,y,z) on duplicate key update lat=y, lng=z
/*!*/;
# at 249935606
#150730 14:16:06 server id 1  end_log_pos 249936255 CRC32 0x2a52c734    Query   thread_id=40    exec_time=0     error_code=0
SET TIMESTAMP=1438265766/*!*/;
INSERT INTO table(txnid) VALUES ('885851438265675046')
/*!*/;
# at 249936255
#150730 14:16:06 server id 1  end_log_pos 249936514 CRC32 0x6cd85eb5    Query   thread_id=40    exec_time=0     error_code=0
SET TIMESTAMP=1438265766/*!*/;
INSERT INTO table2(x) VALUES (y)
/*!*/;
# at 249936514
#150730 14:16:06 server id 1  end_log_pos 249936545 CRC32 0xceb9ec56    Xid = 9406873
COMMIT/*!*/;

Nhật ký truy vấn

150730 14:16:04    40 Query ...
....
40 Query     select count(*) from table where txnid = '885851438265675046'
                   40 Query     select @@session.tx_read_only
                   40 Query     INSERT INTO table(txnid) VALUES ('885851438265675046')
                   40 Query     select @@session.tx_read_only
                   40 Query     INSERT INTO table2(x) values(y)
                   40 Query     commit
....
150730 14:16:07    36 Query     select pp.*, b.create_date from table pp left join bill b on pp.bill_id = b.bill_id where pp.txnid = '885851438265675046'

Thật kỳ lạ, Đầu tiên insert(249935389) không nên là một phần của giao dịch. Đó là một lệnh gọi API riêng biệt và hoàn toàn không liên quan. Nó có thể là mùa xuân trộn nó với giao dịch hoặc tôi đang đọc nhật ký sai? AFAIK vì nó nằm trên cùng một chủ đề, nó ngụ ý chèn trong giao dịch.

Hai insertsphần tiếp theo là một phần của giao dịch và có vẻ như nó cam kết. (249936514). Bây giờ truy vấn chọn (cuối cùng trong nhật ký chung) chạy sau cam kết và nó không thấy dữ liệu. Nó trả về 0 hàng. Làm thế nào điều này có thể xảy ra khi xem xét dữ liệu làcommitted ? Hoặc là commitkhông phải trên chủ đề 40? Vì nó không có id chủ đề.

Để tóm tắt tôi có hai câu hỏi.

  1. BEGINtrong binlog trướcINSERT INTO user_geo_loc (không phải là một phần của giao dịch), đây có phải là lỗi với spring / Jdbc hoặc MySql chỉ đơn giản là làm điều này vì nó biết giao dịch này đã được cam kết (vì các giao dịch được ghi vào binlog khi chúng có đã thành công) và do đó sẽ không bao giờ được khôi phục.

  2. Đưa ra cam kết xảy ra trước khi chọn (cam kết là lúc 14:16:06 và chọn là lúc 14:16:07) làm thế nào mà lựa chọn không trả về hàng được chèn bởi giao dịch?

Điều này là vô cùng bối rối. Bất kỳ trợ giúp sẽ được đánh giá cao

Lưu ý: Các truy vấn trong cả bin và nhật ký truy vấn đã được chỉnh sửa để xóa thông tin nhạy cảm. Nhưng bản chất của các truy vấn vẫn giữ nguyên

Chỉnh sửa: Cập nhật với nhật ký chung và nhật ký truy vấn với một ví dụ chi tiết.


Bạn đã gắn thẻ 5.5, nhưng đề cập đến 5.6; đó là cái gì Có nhân rộng liên quan?
Rick James

@RickJames xin lỗi, đó là 5.6.19. Tôi đã cập nhật câu hỏi với ví dụ từ cả truy vấn và nhật ký bin. Ngoài ra không có bản sao liên quan Tôi chỉ bật nhật ký bin sau khi nhận thấy sự cố để gỡ lỗi. Cảm ơn
Ahmed Aeon Axan

Cảm ơn, điều đó giúp. Tôi không thấy một BEGINhoặc START TRANSACTION. Bạn, thay vào đó, sử dụng autocommit=0? (Tôi thích bắt đầu ... cam kết; nó làm cho phạm vi của giao dịch rõ ràng.)
Rick James

Vì vậy, khung (mùa xuân) quản lý các giao dịch và nó thường đặt autocommit = 0 và cam kết ở cuối. Tôi đoán chúng ta không thấy autocommit = 0 ở đây vì kết nối đã ở trạng thái đó.
Ahmed Aeon Axan

Câu trả lời:


3

Tôi cố gắng đưa ra một giả thuyết về câu hỏi thứ hai:

Đưa ra cam kết xảy ra trước khi chọn (cam kết là lúc 14:16:06 và chọn là lúc 14:16:07) làm thế nào mà lựa chọn không trả về hàng được chèn bởi giao dịch?

Giao dịch được quản lý bởi Spring. Vì vậy, có thể là trước khi chạy selectmùa xuân đã tăngstart transaction hoặc nó đã sử dụng kết nối để chạy một truy vấn khác.

Tôi bắt đầu một phiên đầu tiên trong đó tôi mô phỏng một phần chèn vào bảng t:

session1> create table t (i int auto_increment primary key);
Query OK, 0 rows affected (0,32 sec)

session1> insert into t values();
Query OK, 1 row affected (0,00 sec)

session1> select * from t;
+---+
| i |
+---+
| 1 |
+---+
1 row in set (0,00 sec)

session1> start transaction;
Query OK, 0 rows affected (0,00 sec)

session1> insert into t values();
Query OK, 1 row affected (0,00 sec)

Tôi tạo một phiên mới, session2, trong đó autocommitđược đặt thành 0. Trong phiên mới này, một giao dịch được bắt đầu ngầm khi chạy một lựa chọn.

session2> set autocommit = 0;
Query OK, 0 rows affected (0,00 sec)

session2> select * from t;  -- this starts a transaction
+---+
| i |
+---+
| 1 |
+---+
1 rows in set (0,00 sec)

Di chuyển đến session1 để cam kết chèn.

session1> commit;

Bây giờ chuyển lại sang session2:

session2> select * from t;
+---+
| i |
+---+
| 1 |
+---+
1 row in set (0,00 sec)

Phiên 2 không thể thấy hàng vừa chèn. Nếu a commitđược nâng lên trong session2, chúng ta có thể thấy hàng mới được chèn trong session1

session2> commit
1 row in set (0,00 sec)

session2> select * from t;
+---+
| i |
+---+
| 1 |
| 2 |
+---+
2 rows in set (0,00 sec)

Nhật ký chung trông như:

150804 14:04:10     2 Query select * from t

150804 14:04:30     1 Query start transaction
150804 14:04:39     1 Query insert into t values ()
150804 14:04:44     1 Query commit
150804 14:04:51     2 Query select * from t

150804 14:05:07     2 Query commit
150804 14:05:10     2 Query select * from t

Hàng đầu tiên có liên quan đến phiên 2. Đó là khi phiên 2 mở giao dịch.

Tôi không biết nếu đây là những gì xảy ra trong trường hợp của bạn. Bạn có thể kiểm tra nhật ký chung của mình nếu Connection_id 36 được sử dụng cho các truy vấn khác. Hãy cho chúng tôi biết.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.