Error
Error Code:
1717
MariaDB Error 1717: Unsafe CREATE IGNORE SELECT
Description
This error indicates that a `CREATE TABLE ... IGNORE SELECT` statement is considered unsafe for replication. It occurs because the `IGNORE` clause's behavior depends on the non-deterministic order of rows returned by the `SELECT` query, which can lead to inconsistencies between master and slave servers in a replication setup.
Error Message
CREATE... IGNORE SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave.
Known Causes
3 known causesNon-Deterministic SELECT Order
The `SELECT` query within `CREATE ... IGNORE SELECT` lacks an `ORDER BY` clause, resulting in an unpredictable row retrieval order.
Statement-Based Replication (SBR)
The use of `CREATE ... IGNORE SELECT` in a statement-based replication setup, where SQL statements are replicated directly without accounting for non-deterministic behavior.
Potential for Data Divergence
The varying row order between master and slave can cause the `IGNORE` clause to process different rows, leading to data inconsistencies across the replicated systems.
Solutions
3 solutions available1. Remove IGNORE Keyword and Handle Duplicates Explicitly medium
Eliminate the problematic IGNORE keyword and implement explicit duplicate handling.
1
Identify the `CREATE TABLE ... IGNORE SELECT ...` statement that is causing the error.
2
Remove the `IGNORE` keyword from the statement. This will cause the statement to error out on duplicate key violations, which is the desired behavior for preventing unexpected data loss.
CREATE TABLE new_table AS SELECT col1, col2 FROM source_table WHERE condition;
3
If you intend to allow duplicates and want to ignore them during insertion into an existing table, use `INSERT IGNORE` instead of `CREATE TABLE ... IGNORE SELECT`.
INSERT IGNORE INTO existing_table (col1, col2) SELECT col1, col2 FROM source_table WHERE condition;
4
If you need to ensure uniqueness and want to decide how to handle duplicates (e.g., update existing rows, log them), implement custom logic. This might involve using `INSERT ... ON DUPLICATE KEY UPDATE` or a multi-step process.
INSERT INTO existing_table (col1, col2) SELECT col1, col2 FROM source_table WHERE condition ON DUPLICATE KEY UPDATE col2 = VALUES(col2);
2. Ensure Deterministic SELECT Order with ORDER BY medium
Force a predictable row order to make IGNORE SELECT behavior consistent.
1
Locate the `CREATE TABLE ... IGNORE SELECT ...` statement.
2
Add an `ORDER BY` clause to the `SELECT` statement to ensure a deterministic order of rows. This order should be based on unique columns or a combination of columns that guarantees uniqueness. For example, if `id` is a unique primary key, use it.
CREATE TABLE new_table AS SELECT col1, col2 FROM source_table WHERE condition ORDER BY id;
3
Understand that even with `ORDER BY`, the `IGNORE` keyword still suppresses errors for rows that would violate unique constraints *during the creation process*. If your goal is to prevent data loss due to duplicates, this approach might still mask issues. It's generally better to explicitly handle duplicates as in Solution 1.
3. Replicate Data in a Single Transaction (for existing tables) medium
Use a transactional approach for inserting data into an existing table, ensuring atomicity.
1
If you are trying to populate an existing table and want to avoid duplicates, start a transaction.
START TRANSACTION;
2
Use `INSERT IGNORE` within the transaction to insert data. This will insert rows that don't violate unique constraints and silently skip those that do.
INSERT IGNORE INTO existing_table (col1, col2) SELECT col1, col2 FROM source_table WHERE condition;
3
Commit the transaction if the insertion is successful.
COMMIT;
4
If you need to explicitly handle duplicates (e.g., update them), use `INSERT ... ON DUPLICATE KEY UPDATE` within the transaction.
INSERT INTO existing_table (col1, col2) SELECT col1, col2 FROM source_table WHERE condition ON DUPLICATE KEY UPDATE col2 = VALUES(col2);
5
If any part of the operation fails, you can rollback the transaction.
ROLLBACK;