Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Загадка... / 3 сообщений из 3, страница 1 из 1
30.11.2016, 13:48
    #39357635
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загадка...
Для начала - выжимка из лога консоли. Чтобы удивить и заинтересовать. Пропущены некоторые команды, которые никак не влияют на показанную таблицу:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
mysql> SELECT * FROM t1;
+---+------------------+
| a | message          |
+---+------------------+
| 1 | Testing          |
| 2 | table            |
| 3 | t1               |
| 4 | Testing table t1 |
+---+------------------+
4 rows in set (0.00 sec)

-- пропущен SELECT из другой таблицы

mysql>  INSERT INTO t1 (message) VALUES ('Testing table t1');
Query OK, 1 row affected (0.00 sec)

-- пропущен SELECT из другой таблицы

mysql> SELECT * FROM t1;
+---+------------------+
| a | message          |
+---+------------------+
| 5 | Testing table t1 |
+---+------------------+
1 row in set (0.00 sec)



Никаких триггеров, процедур, эвентов и других пользователей. Короче, никаких подвохов.

Как это может быть?

Что это было на самом деле.
Суть проблемы - очищенные записи не сразу удаляются из частных таблиц. Суть происходящего демонстрирует полный лог консоли.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
Server version: 5.7.16-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

-- Создаём отдельные таблицы
mysql>  CREATE TABLE t1 (
    ->     a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->     message CHAR(20)) ENGINE=MyISAM;
Query OK, 0 rows affected (0.08 sec)

mysql>  CREATE TABLE t2 (
    ->     a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->     message CHAR(20)) ENGINE=MyISAM;
Query OK, 0 rows affected (0.05 sec)

-- Заполняем их данными
mysql>  INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql>  INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

-- Создаём MERGE таблицу 
mysql>  CREATE TABLE total (
    ->     a INT NOT NULL AUTO_INCREMENT,
    ->     message CHAR(20), INDEX(a))
    ->     ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
Query OK, 0 rows affected (0.04 sec)

-- Добавляем данные в отдельные таблицы
mysql>  INSERT INTO t1 (message) VALUES ('Testing table t1');
Query OK, 1 row affected (0.00 sec)

mysql>  INSERT INTO t2 (message) VALUES ('Testing table t2');
Query OK, 1 row affected (0.00 sec)

-- Проверяем наличие добавленных записей
mysql> SELECT * FROM t1;
+---+------------------+
| a | message          |
+---+------------------+
| 1 | Testing          |
| 2 | table            |
| 3 | t1               |
| 4 | Testing table t1 |
+---+------------------+
4 rows in set (0.00 sec)

mysql> SELECT * FROM t2;
+---+------------------+
| a | message          |
+---+------------------+
| 1 | Testing          |
| 2 | table            |
| 3 | t2               |
| 4 | Testing table t2 |
+---+------------------+
4 rows in set (0.00 sec)

mysql> SELECT * FROM total;
+---+------------------+
| a | message          |
+---+------------------+
| 1 | Testing          |
| 2 | table            |
| 3 | t1               |
| 4 | Testing table t1 |
| 1 | Testing          |
| 2 | table            |
| 3 | t2               |
| 4 | Testing table t2 |
+---+------------------+
8 rows in set (0.00 sec)

-- Чистим MERGE таблицу 
mysql> TRUNCATE total;
Query OK, 0 rows affected (0.00 sec)

-- Проверяем, что она очистилась
mysql> SELECT * FROM total;
Empty set (0.00 sec)

-- А вот и факап !
mysql> SELECT * FROM t1;
+---+------------------+
| a | message          |
+---+------------------+
| 1 | Testing          |
| 2 | table            |
| 3 | t1               |
| 4 | Testing table t1 |
+---+------------------+
4 rows in set (0.00 sec)

mysql> SELECT * FROM t2;
+---+------------------+
| a | message          |
+---+------------------+
| 1 | Testing          |
| 2 | table            |
| 3 | t2               |
| 4 | Testing table t2 |
+---+------------------+
4 rows in set (0.00 sec)

-- Вставляем в MERGE таблицу запись (метод LAST - т.е. вставка выполнится в t2)
mysql>  INSERT INTO total (message) VALUES ('Testing table total');
Query OK, 1 row affected (0.00 sec)

-- Всё верно - одна запись.
mysql> SELECT * FROM total;
+---+---------------------+
| a | message             |
+---+---------------------+
| 1 | Testing table total |
+---+---------------------+
1 row in set (0.00 sec)

-- Таблица t1 не затрагивалась, в ней факап продолжается
mysql> SELECT * FROM t1;
+---+------------------+
| a | message          |
+---+------------------+
| 1 | Testing          |
| 2 | table            |
| 3 | t1               |
| 4 | Testing table t1 |
+---+------------------+
4 rows in set (0.00 sec)

-- а таблица t2 - затрагивалась, и в ней всё подровнялось
mysql> SELECT * FROM t2;
+---+---------------------+
| a | message             |
+---+---------------------+
| 1 | Testing table total |
+---+---------------------+
1 row in set (0.00 sec)

-- Вставим запись в первую таблицу
mysql>  INSERT INTO t1 (message) VALUES ('Testing table t1');
Query OK, 1 row affected (0.00 sec)

-- В MERGE таблицу запись попала нормально
mysql> SELECT * FROM total;
+---+---------------------+
| a | message             |
+---+---------------------+
| 5 | Testing table t1    |
| 1 | Testing table total |
+---+---------------------+
2 rows in set (0.00 sec)

-- Да и в t1 всё стало как ожидалось изначально
mysql> SELECT * FROM t1;
+---+------------------+
| a | message          |
+---+------------------+
| 5 | Testing table t1 |
+---+------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM t2;
+---+---------------------+
| a | message             |
+---+---------------------+
| 1 | Testing table total |
+---+---------------------+
1 row in set (0.00 sec)

...
Рейтинг: 0 / 0
30.11.2016, 14:20
    #39357662
Melkij
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загадка...
Akina, у меня не получилось воспроизвести на 5.7.15.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
mysql> CREATE TABLE t1 (
    -> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> message CHAR(20)) ENGINE=MyISAM;
Query OK, 0 rows affected (0,00 sec)

mysql> 
mysql> CREATE TABLE t2 (
    -> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> message CHAR(20)) ENGINE=MyISAM;
Query OK, 0 rows affected (0,00 sec)

mysql> 
mysql> INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');
Query OK, 3 rows affected (0,00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');
Query OK, 3 rows affected (0,00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> 
mysql> CREATE TABLE total (
    ->         a INT NOT NULL AUTO_INCREMENT,
    ->         message CHAR(20), INDEX(a))
    ->         ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
Query OK, 0 rows affected (0,00 sec)

mysql> 
mysql> INSERT INTO t1 (message) VALUES ('Testing table t1');
Query OK, 1 row affected (0,00 sec)

mysql> INSERT INTO t2 (message) VALUES ('Testing table t2');
Query OK, 1 row affected (0,00 sec)

mysql> 
mysql> SELECT * FROM total;
+---+------------------+
| a | message          |
+---+------------------+
| 1 | Testing          |
| 2 | table            |
| 3 | t1               |
| 4 | Testing table t1 |
| 1 | Testing          |
| 2 | table            |
| 3 | t2               |
| 4 | Testing table t2 |
+---+------------------+
8 rows in set (0,00 sec)

mysql> SELECT * FROM t1;
+---+------------------+
| a | message          |
+---+------------------+
| 1 | Testing          |
| 2 | table            |
| 3 | t1               |
| 4 | Testing table t1 |
+---+------------------+
4 rows in set (0,00 sec)

mysql> SELECT * FROM t2;
+---+------------------+
| a | message          |
+---+------------------+
| 1 | Testing          |
| 2 | table            |
| 3 | t2               |
| 4 | Testing table t2 |
+---+------------------+
4 rows in set (0,00 sec)

mysql> 
mysql> TRUNCATE total;
Query OK, 0 rows affected (0,00 sec)

mysql> 
mysql> SELECT * FROM t1;
Empty set (0,00 sec)

mysql> SELECT * FROM t2;
Empty set (0,00 sec)

mysql> SELECT * FROM total;
Empty set (0,00 sec)

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.15    |
+-----------+
1 row in set (0,00 sec)



Возможно, вы попадаете вот в этот кусок (несмотря на то, что написано про mapped into MERGE, а не наоборот):
http://dev.mysql.com/doc/refman/5.7/en/merge-table-problems.html
manYou should not use ANALYZE TABLE, REPAIR TABLE, OPTIMIZE TABLE, ALTER TABLE, DROP TABLE, DELETE without a WHERE clause, or TRUNCATE TABLE on any of the tables that are mapped into an open MERGE table. If you do so, the MERGE table may still refer to the original table and yield unexpected results. To work around this problem, ensure that no MERGE tables remain open by issuing a FLUSH TABLES statement prior to performing any of the named operations.
Попробуйте дёрнуть flush tables перед truncate.
...
Рейтинг: 0 / 0
30.11.2016, 14:29
    #39357670
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загадка...
MelkijПопробуйте дёрнуть flush tables перед truncate.
Всё верно, но только не перед, а после. Думаю, это был результат некорректного фикса маппинга TRUNCATE на DELETE (и сопутствующей баги со срабатыванием ON DELETE триггера при TRUNCATE).

Но, сцуко, как же я удивился поначалу...
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Загадка... / 3 сообщений из 3, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]