Unsafe Statements for Statement-based Replication
The terms master and slave have historically been used in replication, and MariaDB has begun the process of adding primary and replica synonyms. The old terms will continue to be used to maintain backward compatibility - see MDEV-18777 to follow progress on this effort.
Contents
A safe statement is generally deterministic; in other words the statement will always produce the same result. For example, an INSERT statement producing a random number will most likely produce a different result on the master than on the slave, and so cannot be replicated safely. 복제 안전한 구문은 일반적으로 결정론적(deterministic)입니다. 즉, 동일한 명령문이 항상 동일한 결과를 만들어냅니다. 한편, 난수를 생성하는 INSERT문과 같은 구문은 대부분의 경우에 프라이머리와 레플리카에서 다른 결과를 만들어내므로 복제 안전하지 않습니다
When an unsafe statement is run, the current binary logging format determines how the server responds. 안전하지 않은 구문이 실행되면, 현재의 바이너리 로그 형식이 서버가 어떻게 반응할지 결정합니다.
- If the binary logging format is statement-based (the default until MariaDB 10.2.3), unsafe statements generate a warning and are logged normally.
- 바이너리 로그 형식이 statement-based (MariaDB 10.2.3까지의 기본 설정값)인 경우, 안전하지 않은 구문은 경고를 발생시키고 정상적으로 로깅됩니다.
- If the binary logging format is mixed (the default from MariaDB 10.2.4), unsafe statements are logged using the row-based format, while safe statements use the statement-based format.
- 바이너리 로그 형식이 mixed (MariaDB 10.2.4부터의 기본 설정값)인 경우, 안전하지 않은 구문은 row-based format으로 로깅되고 안전한 구문은 statement-based format으로 로깅됩니다.
- If the binary logging format is row-based, all statements are logged normally, and the distinction between safe and unsafe is not made.
- 바이너리 로그 형식이 row-based인 경우, 모든 구문이 정상적으로 로깅되고 안전한 구문과 안전하지 않은 구문이 구분되지 않습니다.
MariaDB tries to detect unsafe statements. When an unsafe statement is issued, a warning similar to the following is produced: MariaDB는 안전하지 않은 구문을 탐지하려고 시도합니다. 안전하지 않은 구문이 발견되면 아래와 같은 경고가 생성됩니다:
Note (Code 1592): Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted.
MariaDB also issues this warning for some classes of statements that are safe. MariaDB는 안전한 구문의 일부 클래스에 대해서도 경고를 발생시킵니다.
안전하지 않은 구문
The following statements are regarded as unsafe: 다음 구문들은 안전하지 않은 것으로 간주됩니다:
- INSERT ... ON DUPLICATE KEY UPDATE statements upon tables with multiple primary or unique keys, as the order that the keys are checked in, and which affect the rows chosen to update, is not deterministic. Before MariaDB 5.5.24, these statements were not regarded as unsafe. In MariaDB 10.0 this warning has been removed as we always check keys in the same order on the master and slave if the master and slave are using the same storage engine.
- INSERT ... ON DUPLICATE KEY UPDATE문은 여러 개의 기본 키 또는 유니크 키를 가지는 테이블에 대해 키를 체크하는 순서가 결정론적이지 않고, 이는 UPDATE하는 행에 영향을 미칩니다. MariaDB 5.5.24 이전까지는 이 구문이 안전하지 않은 것으로 간주되지 않았습니다. MariaDB 10.0 에서는 프라이머리와 레플리카가 같은 스토리지 엔진일 경우 항상 동일한 순서로 키를 체크하므로 이 경고가 제거되었습니다.
- INSERT-DELAYED. These statements are inserted in an indeterminate order.
- INSERT-DELAYED문은 불확실한 순서로 삽입됩니다.
- INSERT's on tables with a composite primary key that has an AUTO_INCREMENT column that isn't the first column of the composite key.
- AUTO_INCREMENT를 사용하는 컬럼이 복합 기본키에 포함되어 있고, 해당 컬럼이 복합 키의 첫번째 컬럼은 아닌 테이블에 대한 INSERT문
- When a table has an AUTO_INCREMENT column and a trigger or stored procedure executes an UPDATE statement against the table. Before MariaDB 5.5, all updates on tables with an AUTO_INCREMENT column were considered unsafe, as the order that the rows were updated could differ across servers.
- 테이블에 AUTO_INCREMENT 컬럼이 존재하고, trigger 또는 stored procedure가 해당 테이블에 대해 UPDATE문을 수행하는 경우. MariaDB 5.5 이전에는 AUTO_INCREMENT 컬럼을 가진 테이블에 대한 모든 UPDATE는 안전하지 않은 것으로 간주되었는데, 이는 행이 업데이트되는 순서가 서버별로 다를 수 있기 때문입니다.
- UPDATE statements that use LIMIT, since the order of the returned rows is unspecified. This applies even to statements using an ORDER BY clause, which are deterministic (a known bug). However, since MariaDB 10.0.11,
LIMIT 0
is an exception to this rule (see MDEV-6170), and these statements are safe for replication. - LIMIT를 사용하는 UPDATE. 행이 반환되는 순서가 특정되지 않기 때문입니다. 심지어는 결정론적인 구문인 ORDER BY를 사용하더라도 동일합니다.(이는 알려진 버그입니다.) 그러나 MariaDB 10.0.11부터는
LIMIT 0
는 이 규칙의 예외이고 복제에 안전합니다.(MDEV-6170를 참조하세요.) - When using a user-defined function.
- 사용자 정의 함수를 사용하는 경우.
- Statements using using any of the following functions, which can return different results on the slave:
- 다음 함수를 사용하는 경우 레플리카에서 다른 결과를 반환할 수 있습니다.
- Statements which refer to log tables, since these may differ across servers.
- 로그 테이블을 참조하는 구문. 로그 테이블은 서버마다 다를 수 있습니다.
- Statements which refer to self-logging tables. Statements following a read or write to a self-logging table within a transaction are also considered unsafe.
- 자체 로그 테이블(self-logging table)을 참조하는 구문. 트랜잭션 내에서 자체 로그 테이블에 대한 읽기 또는 쓰기도 안전하지 않은 것으로 간주됩니다.
- Statements which refer to system variables (there are a few exceptions).
- 시스템 변수에 대한 참조문(몇 가지 예외가 있습니다.)
- LOAD DATA INFILE statements (since MariaDB 5.5).
- LOAD DATA INFILE문(MariaDB 5.5부터)
- Non-transactional reads or writes that execute after transactional reads within a transaction.
- 트랜잭션 내에서, 트랜잭션 읽기 이후 수행되는 비 트랜잭션 읽기 또는 쓰기
- If row-based logging is used for a statement, and the session executing the statement has any temporary tables, row-based logging is used for the remaining statements until the temporary table is dropped. This is because temporary tables can't use row-based logging, so if it is used due to one of the above conditions, all subsequent statements using that table are unsafe. The server deals with this situation by treating all statements in the session as unsafe for statement-based logging until the temporary table is dropped.
- 구문에 row-based 형식이 사용되고 구문을 실행한 세션에 임시 테이블이 있는 경우 임시 테이블이 제거되기 전까지는 나머지 구문에 대해 row-based 형식이 적용됩니다. 임시 테이블은 row-based 로깅을 사용할 수 없기 때문에, 위으 조건에 해당하는 경우 임시 테이블을 사용하는 모든 구문이 안전하지 않습니다. 서버는 이 상황을 세션 내의 모든 구문을 statement-based 에 대해 안전하지 않다고 간주합니다.
안전한 구문
The following statements are not deterministic, but are considered safe for binary logging and replication: 다음의 구문들은 결정론적이지 않지만 바이너리 로그와 복제에 안전하다고 간주됩니다:
- CONNECTION_ID()
- CURDATE()
- CURRENT_DATE()
- CURRENT_TIME()
- CURRENT_TIMESTAMP()
- CURTIME()
- LAST_INSERT_ID()
- LOCALTIME()
- LOCALTIMESTAMP()
- NOW()
- UNIX_TIMESTAMP()
- UTC_DATE()
- UTC_TIME()
- UTC_TIMESTAMP()
격리 수준(Isolation Levels)
Even when using safe statements, not all transaction isolation levels are safe with statement-based or mixed binary logging. The REPEATABLE READ and SERIALIZABLE isolation levels can only be used with the row-based format. 안전한 구문을 사용할 때에도, 모든 트랜잭션 격리 수준(transaction isolation levels)이 statement-based 형식 또는 mixed binary 형식에서 안전한 것은 아닙니다. REPEATABLE READ 및 SERIALIZABLE 격리 수준은 row-based 형식에서만 사용이 가능합니다.
This restriction does not apply if only non-transactional storage engines are used. 트랜잭션 미지원 스토리지 엔진만 사용되는 경우 이 제한이 적용되지 않습니다.