MySQL

  • 在开始创建Compute/Database资源之前,需要先完成认证,再将需要的基础资源准备好。基础资源包括VCN/Subnet等相关的网络基础组件。本文将通过简单的示例展示这些基础组件的创建。

    区域/Compartment/AD

    和所有的Provider一样,我们会在Oracle Cloud的provider基础配置中配置好region。在资源创建的时候,核心资源都需要配置compartment_id,可以简单理解为,该资源属于哪个逻辑组(关于Compartment)。例如,一个典型的、简单的VCN的创建代码如下:

    provider "oci" {
      region           = var.region
    }
    
    # 创建一个新的compartment,他的parent compartment是tenancy_id
    resource "oci_identity_compartment" "oic" {
        #Required
        compartment_id = var.tenancy_id
        description = "for database benchmark"
        name = var.naming
    }
    
    resource "oci_core_vcn" "ocv" {
        #Required
        compartment_id = oci_identity_compartment.oic.id
        cidr_block = "172.17.0.0/16"
        display_name = var.naming
    }

    创建一个具备“公网”能力的子网

    这里说的“公网”能力,包括了两个方面:

    • 一个是可以被公网访问,这样就可以ssh登录并管理
    • 一个是可以访问公网,这样就可以通过wget/git/yum等工具安装软件

    这里配置要求比较严谨,与AWS有一些类似。分为以下几个步骤:

    • 创建一个VCN(oci_core_vcn),创建一个对应的子网(oci_core_subnet)
      • 需要注意的是,在创建了VCN之后,OCI Terraform会默认的创建一组:默认的安全组(default_security_list_id)、默认的路由表(default_route_table_id)、默认的dhcp(default_dhcp_options_id)
    resource "oci_core_vcn" "ocv" {
        #Required
        compartment_id = oci_identity_compartment.oic.id
        cidr_block = "172.17.0.0/16"
        display_name = var.naming
        dns_label    = var.naming
    }
    
    # Creates a subnet
    resource "oci_core_subnet" "subnet_primary" {
      availability_domain = data.oci_identity_availability_domain.oad.name
      cidr_block          = "172.17.1.0/24"
      display_name        = "domain_primary"
      dns_label           = "tfsubnet"
      security_list_ids   = [oci_core_vcn.ocv.default_security_list_id]
      compartment_id      = oci_identity_compartment.oic.id
      vcn_id              = oci_core_vcn.ocv.id
      route_table_id      = oci_core_vcn.ocv.default_route_table_id
      dhcp_options_id     = oci_core_vcn.ocv.default_dhcp_options_id
    }
    • 创建一个具备互联网访问规则的网关
    resource "oci_core_internet_gateway" "internet_gateway" {
      compartment_id = oci_identity_compartment.oic.id
      display_name   = "InternetGateway"
      vcn_id         = oci_core_vcn.ocv.id
    }
    
    resource "oci_core_default_route_table" "route_table_for_internet" {
      manage_default_resource_id = oci_core_vcn.ocv.default_route_table_id
      display_name               = "RouteTableForInternet"
    
      route_rules {
        destination       = "0.0.0.0/0"
        destination_type  = "CIDR_BLOCK"
        network_entity_id = oci_core_internet_gateway.internet_gateway.id
      }
    }
    • 最后,添加合适的端口访问规则:
    resource "oci_core_security_list" "osl" {
      compartment_id = oci_identity_compartment.oic.id
      vcn_id         = oci_core_vcn.ocv.id
      display_name   = "${var.naming}SecurityList"
    
      ingress_security_rules {
        protocol  = "6" // tcp
        source    = "0.0.0.0/0"
        stateless = false
    
        tcp_options {
        #   source_port_range {
        #     min = 100
        #     max = 100
        #   }
    
        #  // These values correspond to the destination port range.
          min = 22
          max = 22
        }
      }
    }

    Availability Domains

    和Compartment一样,这是另一个Oracle Cloud上必须得,但是似乎必要性并不强的概念。在Oracle Cloud上,整体的资源位置从大到小:region -> Availability Domains -> Fault Domain。其中,Fault Domain可以理解为其他云的zone的概念,代表了一个IDC机房(可能是相邻的多个building),通常,3个Fault Domain构成一个Availability Domains。在一个Region通常只有一个Availability Domains,也有部分Region有2~3个Availability Domains

    在Terraform中,如果确定了Region,我们需要使用data.oci_identity_availability_domain获取对应availability_domain的信息:

    data "oci_identity_availability_domain" "oad" {
        #Required
        compartment_id = oci_identity_compartment.oic.id
        ad_number = 1
    }

    创建计算资源(Compute)

    选择合适的image

    这里参考了example public_ip.tf@GitHub,使用了较为“直接”的方式(缺乏扩展性)获取需要镜像:

    variable "instance_image_ocid" {
      type = map(string)
    
      default = {
        # See https://docs.oracle.com/en-us/iaas/images/image/abf452f1-bf22-4837-b47b-79945ed26bee/
        # CentOS-7
        ap-tokyo-1  = "ocid1.image.oc1.ap-tokyo-1.aaaaaaaa4hzluwszvbv3m3m27pvly5qm6ldnjgibjxrexuhe4ky5ncijjsra"
      }
    }

    这里的ocid则是根据 Images@Oracle Cloud Infrastructure Documentation 列出的所有镜像选择而来。更具扩展性的做法应该是通过terraform data对象去获取。

    计算实例的配置

    在OCI中,计算实例的配置,相对来说是比较简单的:

    # Creates an instance (without assigning a public IP to the primary private IP on the VNIC)
    resource "oci_core_instance" "oi" {
      availability_domain = data.oci_identity_availability_domain.oad.name
      compartment_id      = oci_identity_compartment.oic.id
      display_name        = var.naming
      fault_domain        = var.zone_primary
      shape               = var.vm_instance_type
      shape_config {
        memory_in_gbs = 2
        ocpus = 1
      }
    
      source_details {
        source_type = "image"
        source_id   = var.instance_image_ocid[var.region]
        boot_volume_size_in_gbs = 50
      }
    
      create_vnic_details {
        assign_public_ip = true
        display_name     = "Vnic${var.naming}"
        subnet_id        = oci_core_subnet.subnet_primary.id
        hostname_label   = var.naming
      }
      metadata = {
        ssh_authorized_keys = var.publickey
      }
      preserve_boot_volume = false
    }

    上面通过:

    • source_details描述了使用的镜像以及启动盘的大小
    • create_vnic_details描述了VNIC的主要配置,包括所属子网、是否有绑定公网IP等
    • metadata则描述了ssh的公钥信息,实现秘钥对登录

    创建数据库实例

    在OCI上创建MySQL实例比较简单,选项也不多,实际在通过Terraform配置也比较简单和顺利:

    resource "oci_mysql_mysql_db_system" "om" {
    
      display_name = var.naming
      compartment_id = oci_identity_compartment.oic.id
    
      availability_domain = data.oci_identity_availability_domain.oad.name
      fault_domain = var.zone_primary
      is_highly_available = true
    
      admin_password = var.db_pass
      admin_username = var.db_user
    
      shape_name = var.rds_instance_type
      data_storage_size_in_gb = 100
    
      subnet_id = oci_core_subnet.subnet_primary.id
    
      ## this appear as optional in documentation
      ## but it is a must to add it
    
      deletion_policy {
        #Optional
        # automatic_backup_retention = false
        final_backup = "SKIP_FINAL_BACKUP"
        is_delete_protected = false
      }
    }

    问题

    400-InvalidParameter

    参数值错误有很多,根据报错这里是automaticBackupRetention相关的参数值错误,对应在Terraform中是deletion_policy中的automatic_backup_retention配置项,该选项并不是必须的,暂时删除解决。

    ╷
    │ Error: 400-InvalidParameter, Request contains an invalid value for 'com.oracle.oci.mysql.model.CreateDbSystemDetails$Builder["deletionPolicy"]->com.oracle.oci.mysql.model.CreateDeletionPolicyDetails$Builder["automaticBackupRetention"]'
    │ Suggestion: Please update the parameter(s) in the Terraform config as per error message Request contains an invalid value for 'com.oracle.oci.mysql.model.CreateDbSystemDetails$Builder["deletionPolicy"]->com.oracle.oci.mysql.model.CreateDeletionPolicyDetails$Builder["automaticBackupRetention"]'
    │ Documentation: https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/mysql_mysql_db_system
    │ API Reference:
    │ Request Target: POST https://mysql.ap-tokyo-1.ocp.oraclecloud.com/20190415/dbSystems
    │ Provider version: 5.42.0, released on 2024-05-19.
    │ Service: Mysql Db System
    │ Operation Name: CreateDbSystem
    │ OPC request ID: ...
    │
    │
    │   with oci_mysql_mysql_db_system.om,
    │   on rds.mysql.tf line 6, in resource "oci_mysql_mysql_db_system" "om":
    │    6: resource "oci_mysql_mysql_db_system" "om" {
    │

    参考链接

  • 概述

    不同的sysbench参数可能对测试结果有一定的影响,如果不注意的话,可能会影响我们对于测试结果的分析,甚至可能会得出错误的测试结论。本文较为详细的介绍sysbench中的--rand-type参数。

    –rand-type 的含义

    --rand-type是sysbench中控制随机数据分布的参数,主要的选项包括了uniform,gaussian,special,pareto,在最新的版本,新增了zipfian。具体的各个随机分布类似介绍如下:

    • uniform 是均匀分布
    • gaussian是正态分布,也叫高斯分布(常见的标准正态分布是其特殊形式)
    • pareto 是帕累托分布,“二八分布”是其特殊形态。该分布在经济学中使用较多,最为常见的例子是认为20%的人拥有80%的财富,即财富在人群中的分布情况。zipfian分布与该分布有一些类似。
    • special 这个是一个奇怪的分布,并不是某个标准分布。应该是Sysbench作者自己定义的某个分布,该分布下取值几乎完全落在中间值附近。

    关于这些分布的讨论可以参考Sysbench在GitHub Issue上的讨论(Use the uniform distribution by default @GitHub Issue),也可以参考Percona相关的讨论文章(Sysbench and the Random Distribution Effect@Percona)。这里使用GitHub Issue中提到的方法,来对这些分布做一个测试,从而大家可以非常好的从可视化的角度去理解这些分布:

    (more…)
  • 近日,MySQL发布了8.4版本,这是一个新的稳定版。在MySQL版本规划中,在2026年8.0.x生命周期结束后,将成为下一个主流稳定版本。

    目前为止,看到该版本并没有特别大的改进。部分改变包括改进了直方图统计信息更新、并行复制、组复制(GR)等,完整的更新可以参考:Changes in MySQL 8.4.0 (2024-04-30, LTS Release)

    MySQL 8.4@OCI性能测试(vs MySQL 8.0)

    Oracle Cloud上也第一时间支持了该版本,于是也通过性能测试的方式,第一时间“尝鲜”了一下该版本。性能测试的趋势图如下:

    注意到,在该Sysbench测试模式下:

    • 当前MySQL 8.4在性能上相对于8.0版本,要低21%(以16并发为参考)
    • 并在超高并发时(并发高于192),性能出现了严重的退化

    作为一个稳定版本,期待官方尽快解决。

    (more…)
  • 在Oracle Cloud Infrastructure(简称OCI,也就是Oracle云)上购买MySQL实例,也会有第三代CPU和第四代CPU规格的选择,分别是:MySQL.VM.Standard.E4.2.32GBMySQL.VM.Standard.E3.2.32GB。本文对比两个版本规格的价格与性能,以供参考。

    结论概述

    E4(AMD EPYC 7J13)、E3(AMD EPYC 7742)同属于AMD系列的CPU,E4似乎主要是在OCI平台,E3较为通用。从性能测试上,可以看到,E4相比于E3有着较为明显的性能优势,以常见的16并发时数据为参考,则E4(MySQL.VM.Standard.E4.2.32GB)相比于E3(MySQL.VM.Standard.E3.2.32GB)性能要高11%。

    这也与之前的,“新一代CPU总是有着更高的性能”的结论一致。

    (more…)
  • 最近,使用sysbench测试时,尝试使用参数--skip_trx=on,很快在实际的测试中就遇到了Duplicate entry的报错,详细的报错如下:

    [ 105s ] thds: 64 tps: 845.68 qps: 15226.20 (r/w/o: 11833.15/3393.04/0.00) lat (ms,95%): 82.96 err/s: 0.00 reconn/s: 0.00
    [ 108s ] thds: 64 tps: 828.65 qps: 14846.32 (r/w/o: 11547.73/3298.59/0.00) lat (ms,95%): 92.42 err/s: 0.00 reconn/s: 0.00
    [ 111s ] thds: 64 tps: 811.67 qps: 14705.36 (r/w/o: 11439.69/3265.67/0.00) lat (ms,95%): 92.42 err/s: 0.00 reconn/s: 0.00
    FATAL: mysql_drv_query() returned error 1062 (Duplicate entry '172978' for key 'sbtest4.PRIMARY') for query 'INSERT INTO sbtest4 (id, k, c, pad) V
    ALUES (172978, 743044, '85734897298-37760631172-31656179599-77290009462-94351507893-97022333300-02606364258-99231394161-86310536236-00514105136',
    '50908340877-51595671823-98046322819-52667567569-56801127593')'
    FATAL: `thread_run' function failed: /usr/share/sysbench/oltp_common.lua:488: SQL error, errno = 1062, state = '23000': Duplicate entry '172978' f
    or key 'sbtest4.PRIMARY'

    也注意到,这个错误的出现有一定的偶发性,但是高并发、长时间压测几乎一定会遇到了(在开启了--skip_trx=on参数后)。因为Sysbench没有对”Duplicate entry”该错误进行处理,测试会退出,也就无法正常完成测试。

    原因分析

    当多个线程并发时,同时没有使用--skip_trx=on,而是使用MySQL默认的auto commit模式,那么在oltp_read_write模型下则一定的概率(小概率)会出现如下的场景:

    时间线线程A线程B
    1生成随机ID X
    2生成随机ID X
    3删除 id 为 X 的记录
    delete from sbtest where id = X
    4删除 id 为 X 的记录
    delete from sbtest where id = X
    5写入 id 为 X 的记录
    insert into sbtest (id…) values ( X …)
    6写入 id 为 X 的记录
    insert into sbtest (id…) values ( X …)

    在上面的场景下,最后一步,线程B再次写入id 为 X 的记录时,则会出现冲突。

    一般来说,即便发生如上情况,也不会出现Duplicate entry的报错。但,组合一些情况,则会出现。例如,在这里,我们使用了--skip_trx=on,那么线程A的如上行为不是在一个事务中,每个操作是一个独立的事务,那么就会出现Duplicate entry报错。

    如果没有使用--skip_trx=on参数,那么在线程2尝试删除记录时,则会遇到锁等待,直到线程1的相关操作全部完成。也就不会出现报错。

    避免该错误

    在开启了–skip_trx=on之后,如果运行时间足够长,且是多线程并发,则几乎一定会遇到如上错误。可以考虑如下方案避免:

    一般来说,因为当表的记录数非常多时,遇到该类冲突的概率比较小,做如上处理并不会影响测试的“一致性”。

    function sysbench.hooks.sql_error_ignorable(err)
      if err.sql_errno == 1062 then -- ER_DUP_ENTRY
        -- do nothing
        -- con:reconnect()
        return true
      end
    end

  • 在MySQL社区的帮助下,终于成功开通了Oracle Cloud,于是,第一时间测试了一下在Oracle Cloud上托管MySQL,看看Oracle MySQL原厂的性能表现如何。

    关注我朋友圈的应该知道,在国内自助的注册Oracle Cloud真的非常不容易。所以,特别感谢Oracle MySQL原厂工程师徐轶韬的帮助,他也是《MySQL高可用解决方案-从主从复制到InnoDB Cluster架构》的作者,他的公众号是“MySQL解决方案工程师”,感兴趣可以关注他的公众号。

    回到正文,Oracle Cloud的全称是”Oracle Cloud Infrastructure”,也经常被简称为”OCI”。在OCI上提供的MySQL服务,相较于AWS、阿里云来说,产品形态也比较简单。首先,托管MySQL在分类“Databases->MySQL HeatWave->DB Systems”这个类目下,在实例创建过程中,涉及的选项不算多,但是因为名词/定义与其他云厂商有一些不同,所以这里做一些解释。Oracle Cloud上的托管MySQL主要选项为:

    • 高可用类型(单节点/standalone、三节点/HA)
    • 规格大小
    • 主可用区选择
    • 空间大小(IOPS/吞吐量与此相关)

    在本次测试中,一共进行了三组测试。规格大小统一为:2 OCPU(Oracle CPU)32GB,100GB存储(对应的7500 IOPS),规格代码为MySQL.VM.Standard.E4.2.32GB。三组测试对比项分别为:单节点 vs 三节点和同可用区 vs 跨可用区。三组测试具体为:跨可用区的三节点测试、同可用区的三节点测试、同可用区的单节点测试。详细参数表如下:

    整体性能趋势图

    整体上,OCI上的MySQL高可用版本(MGR三节点)性能要比单节点低约20%。在三节点的两次测试下,跨可用区与同可用区有着几乎相同的性能表现,从延迟上来看,也非常接近,可用区之间的延迟约为百微秒级别。

    相比于其他云厂商,OCI上的MySQL性能表现,并不算高的。从架构层面,Oracle MySQL是唯一一个选择了MGR来实现高可用、跨可用区数据一致性的。

    OCI上的区域与可用区

    在MySQL的实例创建过程中,会有一些诸如:AD、FD(Fault Domins)等选项。这是OCI特有的关于区域、可用区等选项。关于区域和可用区的概念,Oracle Cloud与其他云厂商虽然都是相同的概念,但是用了完全不同的名称,也是非常容易让人困惑的。

    在Oracle中,分了几层概念:Region->Availability Domains->Fault Domains。

    • Region与其他云厂商区域概念相同;
    • Fault Domains则与其他云厂商的“可用区”对应;
    • 在OCI中,通常三个为一组的Fault Domains会组成一个“Availability Domains”。大部分的Oracle Region中只有一个Availability Domains,也有部分region有3个Availability Domains(参考),所以在MySQL的配置选项中会有AD、FD等缩写词语。

    Oracle Cloud上MySQL实例的数据可靠性架构

    OCI上的MySQL使用的MGR来实现高可用、高可靠(参考:High Availability@Oracle Cloud Infrastructure DocumentationGroup Replication@MySQL Documentation)。三个不同的MySQL节点分布在三个不同的FD,每个节点使用的存储是OCI上的Block Volume(参考),以iSCSI方式使用,类型是“Higher Performance”(此外,还有Balanced、Ultra High Performance、Lower Cost三种Block Volume)。

    根据参数配置来看,Oracle Cloud提供的MySQL三节点是通过MGR实现的,使用的是group_replication_single_primary_mode模式。

    mysql> show variables like '%group_replication_single_primary_mode%';
    +---------------------------------------+-------+
    | Variable_name                         | Value |
    +---------------------------------------+-------+
    | group_replication_single_primary_mode | ON    |
    +---------------------------------------+-------+
    1 row in set (0.00 sec)

    其他说明

    • Oracle Cloud的MySQL没有提供两节点选项
    • 产品规格,Oracle Cloud使用的是OCPUs(Oracle CPU,可以理解为core),详细参考:vCPU and OCPU pricing information。相比于其他云厂商的vCPU(大部分时候为超线程)是明显不同的。

    性能测试的原始数据

    2024-01@MySQL at Oracle Cloud Benchmark
    host : 10.0.0.74 
    sub_dir : 10.0.0.74 
    ins_code : MySQL.VM.Standard.E4.2.32GB 
    ha_type : ha 
    same_az :  
    region : tokyo 
    storage_size : 100 
    
    sysbench for host :10.0.0.74
    threads|transactions| queries| time |avg/Latency|95%/Latency
          2|       90638| 1812760|300.01|       6.62|       7.84 
          4|      147270| 2945400|300.01|       8.15|      10.09 
          8|      215078| 4301560|300.01|      11.16|      13.70 
         16|      242713| 4854260|300.02|      19.78|      33.72 
         24|      260072| 5201440|300.02|      27.68|      45.79 
         32|      273703| 5474060|300.03|      35.07|      56.84 
         48|      283811| 5676220|300.06|      50.74|      73.13 
         64|      287176| 5743520|300.06|      66.86|     102.97 
         96|      283113| 5662260|300.09|     101.74|     158.63 
        128|      285210| 5704200|300.12|     134.66|     189.93 
        192|           0|       0|  0.00|       0.00|       0.00 
    
    2024-01-14@MySQL at Oracle Cloud Benchmark
    host : 10.0.0.13 
    sub_dir : 10.0.0.13 
    ins_code : MySQL.VM.Standard.E4.2.32GB 
    ha_type : ha 
    same_az : 1 
    region : tokyo 
    storage_size : 100 
    
    sysbench for host :10.0.0.13
    threads|transactions| queries| time |avg/Latency|95%/Latency
          2|       95033| 1900660|300.01|       6.31|       7.56 
          4|      148751| 2975020|300.01|       8.07|      10.27 
          8|      214974| 4299480|300.01|      11.16|      13.70 
         16|      262105| 5242100|300.01|      18.31|      30.81 
         24|      253583| 5071660|300.03|      28.39|      47.47 
         32|      272755| 5455100|300.03|      35.20|      54.83 
         48|      269370| 5387400|300.04|      53.46|      77.19 
         64|      286891| 5737820|300.06|      66.93|     102.97 
         96|      276749| 5534980|300.12|     104.08|     161.51 
        128|      287452| 5749040|300.13|     133.61|     183.21 
        192|           0|       0|  0.00|       0.00|       0.00 
    
    host : 10.0.0.74 
    sub_dir : 10.0.0.74 
    ins_code : MySQL.VM.Standard.E4.2.32GB 
    ha_type : ha 
    same_az :  
    region : tokyo 
    storage_size : 100 
    
    sysbench for host :10.0.0.74
    threads|transactions| queries| time |avg/Latency|95%/Latency
          2|       90638| 1812760|300.01|       6.62|       7.84 
          4|      147270| 2945400|300.01|       8.15|      10.09 
          8|      215078| 4301560|300.01|      11.16|      13.70 
         16|      242713| 4854260|300.02|      19.78|      33.72 
         24|      260072| 5201440|300.02|      27.68|      45.79 
         32|      273703| 5474060|300.03|      35.07|      56.84 
         48|      283811| 5676220|300.06|      50.74|      73.13 
         64|      287176| 5743520|300.06|      66.86|     102.97 
         96|      283113| 5662260|300.09|     101.74|     158.63 
        128|      285210| 5704200|300.12|     134.66|     189.93 
        192|           0|       0|  0.00|       0.00|       0.00 
    
    host : 10.0.0.224 
    sub_dir : 10.0.0.224 
    ins_code : MySQL.VM.Standard.E4.2.32GB 
    ha_type : standalone 
    same_az : 1 
    region : tokyo 
    storage_size : 100 
    
    sysbench for host :10.0.0.224
    threads|transactions| queries| time |avg/Latency|95%/Latency
          2|      102033| 2040660|300.00|       5.88|       7.56 
          4|      186602| 3732040|300.01|       6.43|       8.90 
          8|      281464| 5629280|300.01|       8.53|      12.30 
         16|      333418| 6668360|300.02|      14.40|      31.94 
         24|      345463| 6909260|300.02|      20.84|      47.47 
         32|      359902| 7198040|300.03|      26.67|      56.84 
         48|      353246| 7064920|300.06|      40.77|      78.60 
         64|      370118| 7402360|300.07|      51.88|      99.33 
         96|      380647| 7612940|300.09|      75.67|     134.90 
        128|      372683| 7453660|300.12|     103.05|     164.45 
        192|           0|       0|  0.00|       0.00|       0.00 
    

    参考

    1. High Availability@Oracle Cloud Infrastructure Documentation
    2. Group Replication@MySQL Documentation
    3. vCPU and OCPU pricing information