[MDEV-12958] aria engine transaction logging for a table is enabled by default. Created: 2017-05-30  Updated: 2017-06-13  Resolved: 2017-06-01

Status: Closed
Project: MariaDB Server
Component/s: Documentation, Storage Engine - Aria
Affects Version/s: 10.1.22
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: Yuriy Vasylchenko Assignee: Ian Gilfillan
Resolution: Fixed Votes: 0
Labels: None
Environment:

General Linux



 Description   

The data manipulation statements trigger writes into aria transaction log(s) for the tables created with DEFAULT engine options.
Two side effects: 1) unexpected performance penalty; 2) In combination with MDEV-8587 documented behavior security of the data seriously impaired.

SQL Client

MariaDB [dummydb]> create table test5 (x int, y varchar(1024));
Query OK, 0 rows affected (0.01 sec)
 
MariaDB [dummydb]> show create table test5;
+-------+------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                             |
+-------+------------------------------------------------------------------------------------------------------------------------------------------+
| test5 | CREATE TABLE `test5` (
  `x` int(11) DEFAULT NULL,
  `y` varchar(1024) DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
 
MariaDB [dummydb]> insert into test5 (x,y) values (1,"THIS IS NOT SUPPOSED TO BE THERE");
Query OK, 1 row affected (0.00 sec)
 
MariaDB [dummydb]> flush tables;
Query OK, 0 rows affected (0.01 sec)

console

dummydb$ tr -cd '\11\12\15\40-\176' < ../aria_log.00000001 | grep "THIS"
"[tRpS=*mydb/tesJxdt#t./dummydb/test5t2 THIS IS NOT SUPPOSED TO BE THEREtb/test5          Y-xY-x?G@El`  \G
dummydb$ tr -c '\11\12\15\40-\176' '\n' < ../aria_log.00000001 | grep "THIS"
THIS IS NOT SUPPOSED TO BE THERE

SQL Client

MariaDB [dummydb]> alter table test5 transactional=0;
Query OK, 1 row affected (0.02 sec)                
Records: 1  Duplicates: 0  Warnings: 0
 
MariaDB [dummydb]> insert into test5 (x,y) values (2,"NOW IT IS OK");
Query OK, 1 row affected (0.00 sec)
 
MariaDB [dummydb]> flush tables;
Query OK, 0 rows affected (0.00 sec)

console

dummydb$ tr -c '\11\12\15\40-\176' '\n' < ../aria_log.00000001 | grep "NOW"; echo $?
1



 Comments   
Comment by Sergei Golubchik [ 2017-05-31 ]

Aria is not a default storage engine. If you configured your default storage engine to be Aria, then, naturally, all tables will be created in this engine, unless you specify differently in CREATE TABLE statement.

Comment by Yuriy Vasylchenko [ 2017-05-31 ]

Sergei,

The aria engine was used on purpose (--default-storage-engine=aria).

The problem is that the transaction logging happens for tables created without explicitly specified "TRANSACTIONAL=1" option, while the documentation says opposite:

TRANSACTIONAL= 0 | 1 : Off by default, if set to 1, ...

The documented behavior is reasonable for the engine serving as the replacement for MyISAM and confirmed by Monty in MDEV-5649.

To demonstrate the existence of the problem I created the table using default options and immediately after data insertion I found the unexpected transaction record in the on-disk aria transaction log file.
The details are available in the ticket description.

I was not able to find build-time or run-time configuration options to control this behavior.
It seems that the problem is in the initialization of the MARIA_CREATE_INFO structure rather than in the other places - once transaction logging switched off by altering the table it does not happen anymore.

Comment by Yuriy Vasylchenko [ 2017-06-01 ]

Actually, the simple change fixed the current behavior for me:

storage/maria/ha_maria.cc

--- storage/maria/ha_maria.cc.ori       2017-05-31 16:32:58.347748000 -0700
+++ storage/maria/ha_maria.cc   2017-05-31 16:36:28.208130000 -0700
@@ -3118,7 +3118,7 @@
     born_transactional==1, which confuses some recovery-related code.
   */
   create_info.transactional= (row_type == BLOCK_RECORD &&
-                              ha_create_info->transactional != HA_CHOICE_NO);
+                              ha_create_info->transactional == HA_CHOICE_YES);
 
   if (ha_create_info->tmp_table())
   {

Comment by Sergei Golubchik [ 2017-06-01 ]

The default row format is PAGE, and the PAGE by default means transactional. The logic is:

  • if TRANSACTIONAL=1 was specified, row format will be PAGE. If a user has specified some other row format, Aria issues a warning, but still forces PAGE.
  • If TRANSACTIONAL=0 was specified, the table will be not transactional, the row format will be whatever the user has specified (or PAGE, by default).
  • If TRANSACTIONAL was not specified at all, the row format will be whatever the user has specified (or PAGE, by default), and the table will be transactional if the row format will end up being PAGE and non-transactional otherwise.
Comment by Ian Gilfillan [ 2017-06-01 ]

Added this clarification to the docs

Comment by Yuriy Vasylchenko [ 2017-06-01 ]

I still find the documentation incomplete and somewhat misleading:
1. In the Aria Storage Engine document: "TRANSACTIONAL is ON unless TRANSACTIONAL=0 or ROW_FORMAT other than PAGE options configured for the table" IMO would be better description of the current behavior.
2. Please also document that the data in the encrypted Aria tables should be considered unprotected unless TRANSACTIONAL=0 is explicitly set: unencrypted data will be saved to the transaction log: ROW_FORMAT=PAGE (the default) is mandated by the encryption instructions which in turn means default TRANSACTIONAL=1, according to the newly documented (IMO questionable) behavior.

And Monty was wrong in his comment for MDEV-5649 .

Comment by Ian Gilfillan [ 2017-06-08 ]

monty, serg can you comment on this? The explanation above and in MDEV-5649 do seem to be in conflict, and from my testing Sergei's comment seems accurate. Did something change, or is the distinction simply that the table is transactional by default, but TRANSACTION=1 is not explicitly set by default (even though one implies the other)? In the latter case, this is confusing, and the docs would need some clarifying.

Comment by Sergei Golubchik [ 2017-06-12 ]

I see only one comment that monty made in MDEV-5649, and the only relevant part of it seems to be “TRANSACTIONAL=1 is not on by default”.

This is, strictly speaking, correct. There are three possibilities, TRANSACTIONAL=1, TRANSACTIONAL=0, TRANSACTIONAL not specified. By default, you get the third possibility, not the first. It only means that you will not see TRANSACTIONAL=1 if you do SHOW CREATE TABLE.

Comment by Ian Gilfillan [ 2017-06-13 ]

Monty's comment is unclear as it implies that because TRANSACTIONAL=1 is not explicitly set, the points he lists as taking place when TRANSACTIONAL=1 is set do not occur, when in fact they do, because the table is still transactional by default.

But the behaviour is clear, so I'll look at improving the wording on the docs.

Generated at Thu Feb 08 08:01:49 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.