I have two tables: main and secondary. Both are InnoDB tables.
First of them is partitioned by range, there is currently only one partition in it.
| main | CREATE TABLE `main` (
`main_id` int(10) NOT NULL AUTO_INCREMENT,
`type` varchar(64) DEFAULT NULL,
`username` varchar(64) DEFAULT NULL,
`file_name` varchar(256) DEFAULT NULL,
`the_date` datetime DEFAULT NULL,
`partition_key` int(6) unsigned DEFAULT NULL,
`content` mediumblob,
`completed_date` datetime DEFAULT NULL,
`info` varchar(255) DEFAULT NULL,
KEY `pk_main` (`main_id`),
KEY `idx_main_types` (`type`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (partition_key)
(PARTITION main_201807 VALUES LESS THAN (201808) ENGINE = InnoDB) */ |
Secondary table is not partitioned.
| secondary | CREATE TABLE `secondary` (
`sec_id` int(10) unsigned NOT NULL,
`username` varchar(64) NOT NULL,
`file_name_hash_md5` varchar(32) NOT NULL,
`file_content_hash_md5` varchar(32) DEFAULT NULL,
PRIMARY KEY (`sec_id`),
UNIQUE KEY `unq_secondary_file_name` (`file_name_hash_md5`,`username`),
UNIQUE KEY `unq_secondary_file_content` (`file_content_hash_md5`,`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
I'm running code that works inside a transaction. Transaction isolation is READ_COMMITTED, auto_commit is false. The code inserts one record to main, then one record to secondary, then commits if everything is ok.
But in my scenario the second INSERT fails due to UNIQUE constraint violation. In my code, I catch the corresponding exception before the transaction commits/rolls back and I mark the transaction for rollback. I can see in a debugger that Connection#rollback() actually gets called. I also enabled query log in MariaDB and I see just 3 queries in this connection (after it has been set up): two INSERTs and a ROLLBACK.
But after the rollback, the record that was inserted to main table remains there and does not get rolled back. Also, if I catch a breakpoint inside my code before a COMMIT or ROLLBACK are issued (but after the two INSERTs were executed, one successful, another failed), I can see that main record from a different mysql client session, even though it should not yet be committed.
I know that some actions (like issuing a TRUNCATE in the same session) may cause an implicit commit, but I only have 2 INSERTs and one ROLLBACK in the log.
Why can this happen? And is there any tool that allows to trace such implicit commits (or the reason why the data was committed)?
MariaDB version is 10.0.34-MariaDB-0ubuntu0.16.04.1
Update
In MariaDB with version 10.0.30-MariaDB-1~jessie it works correctly, so it seems that the problem is either that specific version (10.0.34) or Ubuntu-specific patches.
Related
In person_addresses table i am getting error Foreign key constraint is incorrectly formed. My Version is 10.4.24-MariaDB
CREATE TABLE persons (
person_id int(11) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
email varchar(50) DEFAULT NULL,
phone int(11) DEFAULT NULL,
bio text DEFAULT NULL,
dob date DEFAULT NULL,
gender enum('Male','Female','Other') NOT NULL,
status tinyint(4) NOT NULL,
created_at timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (person_id),
UNIQUE KEY email (email),
UNIQUE KEY phone (phone)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE person_addresses (
person_id int(11) NOT NULL ,
address text NOT NULL,
created_at timestamp NOT NULL DEFAULT current_timestamp(),
UNIQUE KEY uc_person_address (person_id,address),
CONSTRAINT fk_person FOREIGN KEY (person_id) REFERENCES persons(person_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
More Detailed Error
------------------------
LATEST FOREIGN KEY ERROR
------------------------
2023-01-11 12:41:52 0x421c Error in foreign key constraint of table `test`.`person_addresses`:
There is no index in table ```test``.``person_addresses``` where the columns appear
as the first columns. Constraint:
FOREIGN KEY (person_id) REFERENCES persons (person_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
Please refer to https://mariadb.com/kb/en/library/foreign-keys/ for correct foreign key definition.Create table `test`.`person_addresses` with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' FOREIGN KEY (person_id) REFERENCES persons (person_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4'.
I think I found a matching bug report in MariaDB: https://jira.mariadb.org/browse/MDEV-29717
The issue is that if the index required for the foreign key is very large, the index is created automatically. But this fails if that index is larger than the index size limit for the storage engine (this should be 3072 bytes in the version of MariaDB you are using, because it defaults to DYNAMIC row format with innodb_large_prefix=on). The text type in your index is too large to be indexed without defining an index prefix. But foreign keys can't use indexes defined with index prefixes.
Unfortunately, because foreign keys are implemented deep in the storage engine, there is little opportunity for a more informative error message to be revealed. This is a problem with the implementation of pluggable storage engines.
The solution in your case should be to change the address column type. It cannot be text, it can only be a varchar that is not too long for the index prefix length limit.
For example, I tested with MariaDB 10.4. https://dbfiddle.uk/5jTX8iFt It fails if address is text, and it works fine if address is varchar(255). I did not test other lengths, I'll leave that to you.
I doubt you need text for an address anyway. Does anyone have an address that requires 64KB?
I have a huge table in a MariaDb (10.4.10-MariaDB-1:10.4.10+maria~bionic) and I am adding a new column using
alter table Appointment add column responsible_organization varchar(256);
The existing table is this:
CREATE TABLE `Appointment` (
`id` VARCHAR(256) NOT NULL,
`version` VARCHAR(24) NOT NULL,
`repetition_ref` VARCHAR(256) NULL DEFAULT NULL,
`type` VARCHAR(256) NULL DEFAULT NULL,
`comment` VARCHAR(2048) NULL DEFAULT NULL,
`description` VARCHAR(2048) NULL DEFAULT NULL,
`end` DATETIME NULL DEFAULT NULL,
`start` DATETIME NULL DEFAULT NULL,
`status` VARCHAR(256) NULL DEFAULT NULL,
`statuschangedate` DATETIME NULL DEFAULT NULL,
`deliverystatus` VARCHAR(256) NULL DEFAULT NULL,
`reasoncancelled` VARCHAR(256) NULL DEFAULT NULL,
`visit_type` VARCHAR(256) NULL DEFAULT NULL,
`modified_db_time` TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3) ON UPDATE current_timestamp(3),
`markedasdeleted` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`, `version`),
INDEX `FKc4f6e4y3ftaya162pwf7v4uj4` (`deliverystatus`),
INDEX `FKeuhxsh83rlweegn404penommb` (`reasoncancelled`),
INDEX `FK5xmurewn61wf4n3of5yx2nsmg` (`visit_type`),
INDEX `modified_db_time` (`modified_db_time`),
CONSTRAINT `FK5xmurewn61wf4n3of5yx2nsmg` FOREIGN KEY (`visittype`) REFERENCES `Coding` (`id`),
CONSTRAINT `FKc4f6e4y3ftaya162pwf7v4uj4` FOREIGN KEY (`deliverystatus`) REFERENCES `CodeableConcept` (`id`),
CONSTRAINT `FKeuhxsh83rlweegn404penommb` FOREIGN KEY (`reasoncancelled`) REFERENCES `CodingDt` (`id`)
)
;
As far as I read the MariaDb documentation it should choose the most efficient algorithm if I don't specify any. I would expect it to use INPLACE at the minimum. But when I run it i can see in the process list that it is running with the state "Copy to tmp table". So this is the COPY algorithm right?
I then tried to force it to use INSTANT as sugested by #o-jones. That gave me this output:
MariaDB [mydb]> alter table Appointment add column responsibleorganisation varchar(256), ALGORITHM=INSTANT;
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
Weird, since I am adding a column.
I am wondering if it has something to do with the table being created on an older version of MariaDb and not having been rebuilt recently. I have found references to this being an issue for tables with old style temporal columns.
The variables old_alter_table and alter_algorithm both have the value DEFAULT
My table has 110+ million rows, so I would have liked to find a way to optimize this.
Any ideas?
MariaDB Server 10.4.10 was released over 2 years ago, in November 2019. Is this repeatable with a more recent version? There have been some fixes to ALTER TABLE since then.
If the problem is repeatable with the latest version in the 10.4 series, I would suggest that you file a bug report at https://jira.mariadb.org with a minimal reproducible test case (CREATE TABLE and ALTER TABLE statements).
With a more recent version, the answer could have been that MDEV-20590 introduced a way to disable instant operations that involve changing the data file format. SET GLOBAL innodb_instant_alter_column_allowed=never; would make ADD COLUMN always rebuild the table, like it did before MariaDB Server 10.3.
I have seen this in cases where a database was created in an earlier version of MariaDB. Sometimes the storage format for some columns has changed, but the upgrade did not rewrite all of the data. Instead it waits until certain schema changes are made and then it modifies that underlying data format. In my cases it was because some of the columns were date/datetime and the temporal storage format had changed in 10.3, but many of my tables were still in the old format. Any schema change I made in 10.4 wanted to update the format for all of those columns, which was a pain for tables with many millions of rows.
If you rebuild the table first using "ALTER TABLE tab_name ENGINE = InnoDB;" then the column add would be able to be added "instantly". Although the alter will take as long as the non-instant column add would. However, there are circumstances where doing the processes separately might be advantageous.
In my case I had to do a manual table rebuild because I could not allow the live table to be locked for as long as the rebuild would take. So I wrote a stored procedure to take the table and create a copy of it gradually, and keep the copy up-to-date. The copy process was throttled to avoid putting to much strain on the db and then once the copy was ready I was able to swap the old and new tables quickly with renames so that the down time was measured in seconds instead of hours. Once the new table was in place I was able to do instant ddl operations on it like normal.
MySQL
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') ENGINE = InnoDB' at line 7
CREATE TABLE IF NOT EXISTS `game_review`.`users` (
`user_id` INT NOT NULL AUTO_INCREMENT,
`email_address` VARCHAR(45) NOT NULL,
`password` VARCHAR(6) NOT NULL,
`username` VARCHAR(20) NOT NULL,
PRIMARY KEY (`user_id`),
UNIQUE INDEX `user_id_UNIQUE` (`user_id` ASC) VISIBLE)
ENGINE = InnoDB;
I expected this to execute properly since I forward engineered it with my ER diagram that I created, but it gives me the error message above.
MariaDB does not support invisible indices, so the VISIBLE and INVISIBLE keywords are not used. Indices are already visible to the optimizer by default, so you could just use:
UNIQUE INDEX user_id_UNIQUE (user_id)
But, a primary key column should already be unique, so you can probably just not even include the unique index.
Side note: MySQL 8+ does support invisible indices, see here, but your MariaDB version seems to not support them.
JBPM issue with Maria DB Galera were Primary key mandatory.
Some tables in JBPM db schema have no primary key.
If I add a primary key column along with them what will be the impact?
Is there nay other way I can get ride of this problem?
Currently we have Mariadb as the only database option to use.
create table EventTypes (
InstanceId bigint not null,
element varchar(255)
) ENGINE=InnoDB;
create table PeopleAssignments_PotOwners (
task_id bigint not null,
entity_id varchar(255) not null
) ENGINE=InnoDB;
Source for MariaDB primary Key mandatory:
mariadb-galera-cluster-known-limitations
Please help.
PeopleAssignments_PotOwners looks like a many:many mapping table between tasks and entities?? If so, then the 'natural' PRIMARY KEY would be
PRIMARY KEY(task_id, entity_id)
(in either order).
Perhaps ditto for the other table?
More discussion of efficiency in many:many tables: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table
If you don't have a 'natural' primary key composed of one (or more) columns, add
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY
When i try to execute the following sql statemant MariaDB give an error:
SQL: TRUNCATE $table CASCADE;
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CASCADE' at line 1 (SQL: TRUNCATE wortmann_products CASCADE;)
is cascade removed in MariaDB or is there something wrong whit the sql statement?
If you are looking to cascade out deletes and updates then the definition has to be stored when the table is created or altered, and will apply to the keys (or FK's in associated tables) allowing child records to be deleted in associated table when parent record is deleted. There are plenty of resources on this, I have listed one here: https://mariadb.com/kb/en/the-mariadb-library/foreign-keys/ - Taken from this resource is the example below:
CREATE TABLE author (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL
) ENGINE = InnoDB;
CREATE TABLE book (
id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) NOT NULL,
author_id SMALLINT UNSIGNED NOT NULL,
CONSTRAINT `fk_book_author`
FOREIGN KEY (author_id) REFERENCES author (id)
ON DELETE CASCADE
ON UPDATE RESTRICT
) ENGINE = InnoDB;