Closed zzhuncle closed 1 year ago
Ubuntu22.04
| Cassandra 4.0.11
| CQL spec 3.4.5
| unixODBC 2.3.9
Apache Cassandra
是一个开源的、分布式的、NoSQL
数据库系统,它最初是由Facebook
开发的,用于处理大量的分布式数据存储。Cassandra
是基于Amazon
的Dynamo
数据库和Google
的Bigtable
数据库的设计理念构建的,因此它结合了两者的优势,提供了高度可扩展性和高性能的数据管理功能。
Cassandra
数据库采用一种称为最终一致性(Eventual Consistency
)的一致性模型,它与传统的关系型数据库中的 ACID
事务模型有所不同。因此,Cassandra
并不使用传统的隔离级别,如 Read Committed
、Repeatable Read
等。而是提供一系列的一致性级别(Consistency Levels
)来控制读写操作的一致性,一致性级别决定了在进行读取或写入操作时,必须成功应答的副本(replica
)数量。主要的一致性级别包括:
根据不同的一致性级别,Cassandra
的读写操作可能会表现出不同的隔离性,但这与传统的关系型数据库中定义的隔离级别是不同的。
Cassandra
支持轻量级事务(Lightweight Transactions
),这可以为某些操作提供一种类似于传统ACID
事务的一致性模型,但它们通常有一定的性能开销,并且不适用于所有用例。即在CQL
语句中使用IF NOT EXISTS
,IF EXISTS
,或IF
子句来实现一些形式的条件更新和删除。这种情况下,Cassandra内部会使用Paxos协议来确保操作的线性一致性,但这会带来更高的延迟和开销。
例如,可以使用IF
条件来保证操作的原子性:
UPDATE mykeyspace.mytable SET value = 123 WHERE key = 'some_key' IF EXISTS;
这个查询只有在some_key
确实存在时才会更新,否则不会进行任何操作。但是,这并不等同于传统的ROLLBACK
命令,因为一旦满足条件并执行了更新,这个操作是不可逆的。
Cassandra
提供了一定程度的事务支持,即通过批处理(Batch
)来实现原子性。在Cassandra
中,可以将多个写操作(如INSERT
、UPDATE
、DELETE
)组合到一个批处理中,这些操作要么全部成功,要么全部失败。但要注意,Cassandra
中的批处理操作不同于关系型数据库中的事务,它不提供隔离性和持久性保证。
BEGIN BATCH
INSERT INTO table1 (column1, column2) VALUES ('value1', 'value2');
UPDATE table2 SET column1 = 'value1' WHERE column2 = 'value2';
DELETE FROM table3 WHERE column1 = 'value1';
APPLY BATCH;
COMMIT
和ROLLBACK
指令Cassandra
不支持传统的SQL
事务,因此也不支持COMMIT
和ROLLBACK
指令。因为Cassandra
不是一个支持ACID
属性的关系型数据库系统。Cassandra
是一个最终一致性(eventual consistency
)的分布式数据库,它主要关注的是可扩展性和高可用性。
INSERT
指令INSERT INTO mytab VALUES (1, 20);
语句在CQL
语言中不被允许,需要完整形式INSERT INTO mytab (k,v) VALUES (1, 20);
实际测试中编写了sql2cql.py
脚本文件将原始测试文件中的INSERT
语句转化为符合CQL
语法的INSERT
语句,其他测试语句保持原状,在单机环境对one
一致性级别进行了测试,由于不支持传统的SQL
事务,因此33
个测试样例中大部分异常,小部分通过,仅有一个测试样例存在死锁情况。
针对除one
以外的一致性级别,由于无法通过ODBC
接口函数直接设置一致性隔离级别,因此暂时没有测试:
即CONSISTENCY ***;
是CQL中的一个命令,用于设置后续查询的一致性级别,但如果直接通过SQLExecDirect
函数执行语句,会报错Malformed SQL Statement: Unrecognized keyword: consistency
,原因为ODBC是通用SQL接口,无法直接发送非标准的SQL命令,如Cassandra
的CONSISTENCY ***;
,对于Cassandra,可以使用专有的驱动器,如DataStax的C++驱动器,在DataStax C++驱动器中,可以这样设置一致性级别:
CassStatement* statement = cass_statement_new("SELECT * FROM table_name", 0);
cass_statement_set_consistency(statement, CASS_CONSISTENCY_QUORUM);
YugabyteDB
测试说明Ubuntu22.04
| yugabyte 2.19.2
| unixODBC 2.3.9
YugabyteDB
是一个高性能的开源分布式 SQL
数据库,旨在支持全球部署的业务关键型应用程序。它结合了传统的 RDBMS
(关系数据库管理系统)的 ACID (原子性、一致性、隔离性、持久性)事务特性和 Internet
级别的水平可扩展性、高可用性和地理分布特性。
YugabyteDB
使用 Raft 分布式共识算法确保强一致性,并且可以容忍网络分区和节点故障,从而实现高可用性。支持多种数据模型,包括文档存储(通过 YCQL
,兼容 Apache Cassandra 查询语言)和关系存储(通过 YSQL
,兼容 PostgreSQL
)。YugabyteDB
支持全局 ACID
事务,这意味着即使在分布式环境中,也能保证数据的完整性和一致性。YugabyteDB
的 SQL
接口(YSQL
)与 PostgreSQL
高度兼容,这使得许多现有的应用程序和工具能够无缝迁移到 YugabyteDB
。YugabyteDB
是为云而生的数据库,支持多云、混合云和 Kubernetes
部署。
YugabyteDB
在事务层支持三种隔离级别:可串行化(Serializable
)、快照(Snapshot
)和已提交读(Read Committed
)。YSQL API
的默认隔离级别本质上是快照隔离(即与PostgreSQL
的可重复读(REPEATABLE READ
)相同)
已提交读(Read committed
):目前处于Beta
阶段。只有在YB-TServer
标志yb_enable_read_committed_isolation
设置为true
时,才支持已提交读隔离。
快照(Snapshot
):默认情况下,yb_enable_read_committed_isolation
标志为false
,在这种情况下,YugabyteDB
事务层的已提交读隔离级别将回退到更严格的快照(Snapshot
)隔离(此时,YSQL
的READ COMMITTED
也会使用快照隔离)。
可串行化(Serializable
),它要求一组可串行化事务的任何并发执行都保证产生与按某种串行顺序(一次一个事务)运行它们相同的效果。
ODBC
YugabyteDB
是 PostgreSQL
兼容的,因此它通常可以使用 PostgreSQL
的 ODBC
驱动程序。
安装 PostgreSQL ODBC
驱动程序:
sudo apt-get install odbc-postgresql
注意:YugabyteDB
的事务隔离级别要在每个事务开始时设置,而不是在线程连接时设置
由于已提交读(Read committed
)特性仅在beta
版本存在,因此并未测试。
快照(Snapshot
)级别的设置命令为:BEGIN TRANSACTION;
(默认隔离级别)
可串行化(Serializable
)级别的设置命令为:BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
MariaDB
数据库测试说明测试环境
Ubuntu 20.04
|MariaDB 10.5.22
|unixODBC 2.3.6
数据库简介
MariaDB
是一个开源的关系数据库管理系统(RDBMS
),由MySQL
的原始开发者创建,作为MySQL
的一个分支。MariaDB
的创建是为了保持开放源代码的自由性,这是由于 Oracle 公司收购了MySQL
的母公司Sun Microsystems
。MariaDB
的开发目标是与MySQL
数据库完全兼容,保证开源性,以及保持开放和透明的开发模式。MariaDB
设计上对MySQL
有很高的兼容性,它能够直接替换MySQL
,且大多数MySQL
代码、表和API
等在MariaDB
中都可以直接使用。MariaDB
支持多种存储引擎,包括InnoDB
、MyRocks
、Aria
等,以满足不同用途的需求。MariaDB
提供了一系列的扩展功能,如分区表、虚拟列、联合引擎等。同时,它还支持线性水平扩展,以支持更大的数据集和更高的查询负载。MariaDB
提供了适用于多种云平台的解决方案,支持容器化部署,例如在Kubernetes
上运行。隔离级别
MariaDB
支持多种事务隔离级别,这些隔离级别决定了多个并发事务如何交互以及在读取数据时可能会看到哪些数据,以下是MariaDB
支持的隔离级别:READ UNCOMMITTED
(读未提交):一个事务可以读取其他未提交事务的修改。这是隔离级别中最低的一种,也是最少使用的一种,因为它可能会导致许多并发问题,如脏读(读取到其他事务未提交的更改)。READ COMMITTED
(读已提交):一个事务只能读取已经提交的其他事务的修改。这意味着它不会看到其他并发事务所做的未提交的更改。这是许多数据库系统的默认隔离级别。REPEATABLE READ
(可重复读):这是MariaDB
的默认隔离级别。在此隔离级别下,事务在开始时锁定其读取的所有数据行,确保这些行在事务结束之前不会被其他事务修改。这样,一个事务在其生命周期内多次读取同一行数据时,总是看到相同的信息。SERIALIZABLE
(串行化):这是隔离级别中最高的一种。在此隔离级别下,事务被执行得就像是序列化的,即一个接一个地执行,没有并发。这意味着在一个事务运行时,其他事务不能并发地访问相同的数据。在选择隔离级别时,通常需要在性能和数据的准确性/一致性之间进行权衡。更高的隔离级别通常提供更好的数据一致性保证,但可能降低并发性能。
实际测试说明
由于
MariaDB
和MySQL
渊源颇深,因此SQL
语法类似,代码基本无需改动,最终在4种隔离级别,33种数据异常上的结果MariaDB 10.5.22
也和MySQL 8.0.20
基本相同。