I read Transaction Isolation Levels in MySQL documentation. Then, only READ COMMITTED and REPEATABLE READ talk about snapshot as shown below:
READ COMMITTED
Each consistent read, even within the same transaction, sets and reads
its own fresh snapshot. ...
REPEATABLE READ
This is the default isolation level for InnoDB. Consistent reads
within the same transaction read the snapshot established by the first
read. ...
snapshot
A representation of data at a particular time, which remains
the same even as changes are committed by other transactions. Used by
certain isolation levels to allow consistent reads.
So, do only READ COMMITTED and REPEATABLE READ use MVCC(Multiversion concurrency control)?
What about READ UNCOMMITTED and SERIALIZABLE?
All transaction isolation levels in InnoDB use MVCC.
Related
So I am trying to learn MySQL and I came across the isolation levels (SERIALIZED, REPEATABLE READ, READ COMMITED, READ UNCOMMITED)
I believe my question is quite simple, but I did not find any information in the web so here it goes:
If I change the default REPEATABLE READ to SERIALIZED or even from READ UNCOMMITED to another higher level of isolation does I have less probabilities of having deadlock problems?
Thanks in advance!
Actually, deadlocks between SELECT operations on the one hand and INSERT or UPDATE on the other hand will be less likely if you use the more permissive READ UNCOMMITTED isolation level for your SELECT operations.
If it's OK for your SELECT operations not to get the results of concurrent changes to your tables, use that.
The possibility of deadlocks is not affected by isolation level. Isolation level changes the behavior of read operations, but deadlock occurs due to write operations. However, isolation level sets fewer locks, hence it can help you to avoid certain lock types (e.g. gap locking).
These tips to avoid dead_lock are very helpful https://www.percona.com/community-blog/2018/09/24/minimize-mysql-deadlocks-3-steps/
So I am trying to understand more about the isolation levels and I read that the READ UNCOMMITED isolation level allows dirty readings which may lead to non-consistent readings. I also read that the
SELECT statements are performed in a nonlocking fashion
So my question is, does this type of isolation uses locks for other statements? For example, if I use the INSERT INTO statement does it acquire locks?
Thanks in advance!
Yes. Locks are still needed to ensure data transactions are atomic.
Also locks ensure that elements like auto_increments values only exist once.
According to the SQL Standard, Repeatable Read should prevent fuzzy reads and dirty reads, while Serializable should also prevent phantom reads.
According to the MySQL documentation:
By default, InnoDB operates in REPEATABLE READ transaction isolation
level. In this case, InnoDB uses next-key locks for searches and index
scans, which prevents phantom rows (see Section 14.2.2.5, “Avoiding
the Phantom Problem Using Next-Key Locking”).
So if Repeatable Read can prevent phantom reads too, what does Serializable offers in return?
Is it that Serializable protects against write skew or read skew and Repeatable Read does not?
The answer can also be found in mysql documentation, quote:
This level is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... LOCK IN SHARE MODE if autocommit is disabled. If autocommit is enabled, the SELECT is its own transaction. It therefore is known to be read only and can be serialized if performed as a consistent (nonlocking) read and need not block for other transactions.
A serializable transaction schedule, when implemented with two-phase locking, prevents read and write skew. That's how it works on SQL Server using locking or on PostgreSQL using their Serializable Snapshot Isolation.
If a shared lock is acquired on the any resource that's being read, then read skew and write skew are prevented as well.
I'm trying to generate a few graphs using the sysbench benchmark (default configuration) trying to show the relationship between deadlocks and isolation level in MySQL.
But I get some strage results: I was under the impression that repeatable read would have more deadlocks than read committed (which is the case), but significantly more than read uncommitted. In fact it turns out that read uncommitted has more deadlocks than either.
Is this normal? And if so, why?
Deadlock can happen in any isolation level. It's hard to tell without the actual tests, but I guess that in case of read commited / repeatable read, if you have to read a value of a row being updated, the value is being read from the rollback log, but in case of read uncommited rollback log is not used, so it the row is locked for update, the read has to wait for the actual value to be written. But it's a wild guess, having more deadlocks in read uncommited is a strange behaviour and most likely - implementation dependent. I would be interested if you could provide the actual tests, and if the test can be repeated in different versions of MySQL.
It seems that mysql select content (as opposed to e.g. count) queries always take at least a table read lock on myisam tables and a row read lock on innodb tables. Is there a way to issue a select content query in mysql (I could change table type if that's required) without having it to grab any locks? I don't mind if the data returned is inconsistent since I will use it for a search index.
With InnoDB you achieve this by setting the transaction isolation level to: READ UNCOMMITTED.
In this isolation level:
SELECT statements are performed in a
nonlocking fashion, but a possible
earlier version of a row might be
used. Thus, using this isolation
level, such reads are not consistent.
This is also called a “dirty read.”
Otherwise, this isolation level works
like READ COMMITTED.
You can either change the default transaction isolation level from the MySQL option file, or else it can be enabled and disabled for a single session:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM table_name;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Further Reading: MySQL Documentation: Set Transaction
in the absence of LOCK TABLES, myisam should be equivalent to read uncommitted mode, but it doesn't actually support any transaction types...
innodb runs in "consistent read" mode (at "repeatable read" isolation level) by default, which the docs suggest won't lock:
If the transaction isolation level is
REPEATABLE READ (the default level),
all consistent reads within the same
transaction read the snapshot
established by the first such read in
that transaction
...
Consistent read is the default mode in
which InnoDB processes SELECT
statements in READ COMMITTED and
REPEATABLE READ isolation levels. A
consistent read does not set any locks
on the tables it accesses, and
therefore other sessions are free to
modify those tables at the same time a
consistent read is being performed on
the table.
...
InnoDB uses a consistent read for
select in clauses like INSERT INTO ...
SELECT, UPDATE ... (SELECT), and
CREATE TABLE ... SELECT that do not
specify FOR UPDATE or LOCK IN SHARE
MODE if the
innodb_locks_unsafe_for_binlog option
is set and the isolation level of the
transaction is not set to
SERIALIZABLE. Thus, no locks are set
on rows read from the selected table.
http://dev.mysql.com/doc/refman/5.0/en/innodb-consistent-read.html