데이터 베이스 MySQL 튜토리얼 MySQL数据库InnoDB存储引擎在线加字段实现原理详解

MySQL数据库InnoDB存储引擎在线加字段实现原理详解

Jun 07, 2016 pm 04:46 PM
innodb

腾讯互娱内部维护了一个MySQL分支,基于官方5.5.24,实现了类似于Oracle 11g的快速加字段功能,这个分支我们内部称为TMySQL。该功

腾讯互娱内部维护了一个MySQL分支,基于官方5.5.24,实现了类似于Oracle 11g的快速加字段功能,这个分支我们内部称为TMySQL。该功能通过扩展存储格式来实现,原理类似于Oracle 11g,以下介绍下其实现原理。

1. GCS行格式

需要在innodb中实现类似oracle的快速加字段功能,仅仅基于原来的行格式是不行的,必须对其进行扩展。为了保证原MySQL和innodb的兼容性,不改变原存储格式的行为,在线加字段功能是通过新增一种innodb行格式GCS(Game Cloud Storage)来实现,从而避免对其他格式造成影响。

虽然说是新增格式,但该格式与原默认的compact是基本一样的,只是新增了关键的Field Count(字段数)控制信息。

下面先回顾下compact行格式

compact聚集索引记录的格式由下图所示,由记录头和记录内容组成。

记录头记录了解析字段的关键信息,其结构下图所示。

Record Extra Bytes:是固定的5字节,表示记录的额外信息。
Nullable Bitmap:记录可空位图,,使用1个bit来表示一个可空字段是否为NULL。
non-NULL Variable-Length Array:非空变长字段数组,表示非空变长字段(如varchar、varbinary)在该行的长度。

关于Compact格式的详细介绍可以参考文章。

compact格式有很重要的两个特点:

字段的定义顺序与存储顺序基本一致(主键除外)
 字段为NULL不占存储空间,只需通过Nullable Bitmap记录。

基于以上特点,实现快速加字段功能GCS格式只需在记录头添加Field Count(字段数),来表示当前记录的字段数,占用1~2字节(若大于127,则使用2字节)。

那么,解析GCS记录的关键逻辑就变为:

假设某GCS记录的Field count记录为x,表字段数为y,那么x

如果x == y或非GCS格式,按原来compact方式解析
 如果x  mysql> create table t1(c1 int, c2 int);
Query OK, 0 rows affected (0.00 sec)

mysql> show table status like 't1'G
*************************** 1. row ***************************
Name: t1
Engine: InnoDB
Version: 10
Row_format: Gcs
Rows: 0
Avg_row_length: 0
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: 2013-09-10 11:44:21
Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)

# 插入大量数据
mysql> insert into t1 values(1,1);
Query OK, 1 row affected (0.00 sec)

# 快速加字段
mysql> alter table t1 add column d1 int not null default 0, add column d2 int;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> select * from t1 limit 1;
+------+------+----+------+
| c1 | c2 | d1 | d2 |
+------+------+----+------+
|1 |1 | 0 | NULL |
+------+------+----+------+
1 row in set (0.00 sec)

--------------------------------------分割线 --------------------------------------

Ubuntu 14.04下安装MySQL

《MySQL权威指南(原书第2版)》清晰中文扫描版 PDF

Ubuntu 14.04 LTS 安装 LNMP Nginx\PHP5 (PHP-FPM)\MySQL

Ubuntu 14.04下搭建MySQL主从服务器

Ubuntu 12.04 LTS 构建高可用分布式 MySQL 集群

Ubuntu 12.04下源代码安装MySQL5.6以及Python-MySQLdb

MySQL-5.5.38通用二进制安装

--------------------------------------分割线 --------------------------------------

2. 兼容性

仅仅新增GCS存储格式,必定导致原来数据的不兼容(每行增加Field Count),只能通过重导数据或alter table来使其支持在线加字段功能。

# compact格式转换为GCS格式
mysql> alter table t_compact row_format=gcs;

如果数据量越大,上述语句所花时间就会越长,这样对升级和使用都带来困难。

为了解决这个问题,GCS格式实现了对compact格式的全面兼容。

在innodb实现中,compact格式记录头的Record Extra Bytes首字节最高位和次高位是保留的,总是为0。因此,GCS记录占用了其中的最高bit,若为1表示使用GCS格式,记录中会包含Field count信息,这里称该bit为控制位。

然而GCS行格式新增的Field Count仅仅是为了表示记录的字段数,如果表不执行加字段操作,该部分其实是不起作用的(记录字段数恒等于表字段数)。换句话说,如果GCS表不执行快速加字段操作,记录其实并不需要存储Field Count信息。

因此,当表第一次快速加字段前,GCS记录可以与compact完全相同,即控制位为0;当第一次快速加字段时,可将加字段前的字段数存储在扩展的数据字典中,用来解析控制位为0的GCS记录(充当记录上的field count信息);新插入或修改的记录,则按照第一节介绍的存储格式进行构建。

最后,这个设计中的GCS记录在第一次快速加字段前可以跟Compact格式是完全一致的。这样做,有两个好处:

第一次在线加字段前,减少每条GCS记录Field Count 1~2字节的存储消耗
 可以支持Compact表快速转换为GCS表,实现快速升级

由于存储格式完全兼容,不管原来的compact表数据量有多少,仅需执行以下命令,修改表的元数据信息,就能将格式快速转换为GCS,从而获得快速加字段功能。

mysql> create table t_compact(c1 int, c2 int) row_format=compact;
 Query OK, 0 rows affected (0.00 sec)

mysql> insert into t_compact values(1,1);
 Query OK, 1 row affected (0.00 sec)

# compact格式非onlie操作,需要拷贝数据
mysql> alter table t_compact add column d1 int;
 Query OK, 1 row affected (0.01 sec)
 Records: 1 Duplicates: 0 Warnings: 0

# online操作,只需修改元数据,不需拷贝数据
mysql> alter table t_compact row_format = gcs;
 Query OK, 0 rows affected (0.00 sec)
 Records: 0 Duplicates: 0 Warnings: 0

# online操作
mysql> alter table t_compact add column d2 int not null default 0;
 Query OK, 0 rows affected (0.00 sec)
 Records: 0 Duplicates: 0 Warnings: 0

这样,TMySQL可实现基于5.5的覆盖升级,对于compact表只需执行alter table row_format = gcs命令就能快速支持在线加字段功能,大大降低升级成本,并且实现加字段前没有存储空间的额外消耗!
3 DML操作

存储格式得以支持,相应的DML操作逻辑需要修改。

select:按照GCS格式进行解析
insert:根据当前表的字段数构造记录中field count和标记控制位
delete:不变
update:原地更新不变;非原地更新走delete+insert,会更新为新的field count

更多详情见请继续阅读下一页的精彩内容:

linux

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

MySQL이 바이너리 콘텐츠에서 InnoDB 행 형식을 보는 방법 MySQL이 바이너리 콘텐츠에서 InnoDB 행 형식을 보는 방법 Jun 03, 2023 am 09:55 AM

InnoDB는 디스크의 테이블에 데이터를 저장하는 스토리지 엔진이므로 종료하고 다시 시작한 후에도 데이터가 계속 존재합니다. 실제 데이터 처리 과정은 메모리에서 일어나므로 디스크에 있는 데이터를 메모리에 로드해야 하며, 쓰기나 수정 요청을 처리하는 경우에도 메모리에 있는 내용을 디스크에 새로 고쳐야 합니다. 그리고 우리는 디스크를 읽고 쓰는 속도가 매우 느리다는 것을 알고 있습니다. 이는 메모리에서 읽고 쓰는 것과는 몇 배 정도 다릅니다. 따라서 테이블에서 특정 레코드를 얻으려면 InnoDB 스토리지 엔진이 읽어야 합니다. 디스크의 레코드가 하나씩? InnoDB가 채택한 방식은 데이터를 여러 페이지로 나누고, 디스크와 메모리 간 상호 작용의 기본 단위로 페이지를 사용하는 것입니다. InnoDB의 페이지 크기는 일반적으로 16입니다.

mysql innodb가 뭐야? mysql innodb가 뭐야? Apr 14, 2023 am 10:19 AM

InnoDB는 MySQL의 데이터베이스 엔진 중 하나이며 현재 MySQL AB의 바이너리 릴리스 표준 중 하나입니다. InnoDB는 이중 트랙 인증 시스템을 채택합니다. 하나는 GPL 인증이고 다른 하나는 독점 소프트웨어입니다. 권한 부여. InnoDB는 트랜잭션 데이터베이스에 선호되는 엔진이며 트랜잭션 보안 테이블(ACID)을 지원합니다. InnoDB는 최대 범위의 동시성을 지원할 수 있는 행 수준 잠금을 지원합니다.

mysql innodb 예외를 처리하는 방법 mysql innodb 예외를 처리하는 방법 Apr 17, 2023 pm 09:01 PM

1. mysql을 롤백하고 다시 설치합니다. 다른 위치에서 이 데이터를 가져오는 문제를 방지하려면 먼저 현재 라이브러리의 데이터베이스 파일(/var/lib/mysql/location)을 백업합니다. 다음으로 Perconaserver5.7 패키지를 제거하고 원래의 이전 5.1.71 패키지를 다시 설치하고 mysql 서비스를 시작했는데 Unknown/unsupportedtabletype:innodb 메시지가 표시되어 정상적으로 시작할 수 없었습니다. 11050912:04:27InnoDB:버퍼풀 초기화 중, 크기=384.0M11050912:04:27InnoDB:완료

Mysql의 innoDB에서 팬텀 읽기를 해결하는 방법 Mysql의 innoDB에서 팬텀 읽기를 해결하는 방법 May 27, 2023 pm 03:34 PM

1. Mysql 트랜잭션 격리 수준 이 네 가지 격리 수준은 여러 트랜잭션 동시성 충돌이 있는 경우 더티 읽기, 반복 불가능 읽기 및 팬텀 읽기 문제가 발생할 수 있으며 innoDB는 반복 읽기 격리 수준 모드에서 이를 해결합니다. 2. 팬텀 읽기란 동일한 트랜잭션에서 첫 번째 트랜잭션에서 범위 쿼리를 실행한 것처럼 전후에 동일한 범위를 두 번 쿼리했을 때 얻은 결과가 일치하지 않는 것을 의미합니다. 이때 조건에 맞는 데이터는 1개뿐이며, 두 번째 트랜잭션에서는 데이터 행을 삽입하여 제출합니다. 첫 번째 쿼리입니다. 첫 번째 트랜잭션의 첫 번째 쿼리와 두 번째 쿼리는 모두 동일합니다.

MySQL 스토리지 엔진 선택 비교: InnoDB, MyISAM 및 메모리 성능 지수 평가 MySQL 스토리지 엔진 선택 비교: InnoDB, MyISAM 및 메모리 성능 지수 평가 Jul 26, 2023 am 11:25 AM

MySQL 스토리지 엔진 선택 비교: InnoDB, MyISAM 및 메모리 성능 지수 평가 소개: MySQL 데이터베이스에서 스토리지 엔진의 선택은 시스템 성능과 데이터 무결성에 중요한 역할을 합니다. MySQL은 다양한 스토리지 엔진을 제공하며, 가장 일반적으로 사용되는 엔진으로는 InnoDB, MyISAM 및 Memory가 있습니다. 이 기사에서는 이 세 가지 스토리지 엔진의 성능 지표를 평가하고 코드 예제를 통해 비교합니다. 1. InnoDB 엔진 InnoDB는 나의 것

MyISAM 및 InnoDB 스토리지 엔진을 사용하여 MySQL 성능을 최적화하는 방법 MyISAM 및 InnoDB 스토리지 엔진을 사용하여 MySQL 성능을 최적화하는 방법 May 11, 2023 pm 06:51 PM

MySQL은 널리 사용되는 데이터베이스 관리 시스템이며, 다양한 스토리지 엔진이 데이터베이스 성능에 서로 다른 영향을 미칩니다. MyISAM과 InnoDB는 MySQL에서 가장 일반적으로 사용되는 두 가지 스토리지 엔진으로 서로 다른 특성을 갖고 있으며 부적절한 사용은 데이터베이스 성능에 영향을 미칠 수 있습니다. 이 기사에서는 이 두 가지 스토리지 엔진을 사용하여 MySQL 성능을 최적화하는 방법을 소개합니다. 1. MyISAM 스토리지 엔진 MyISAM은 MySQL에 가장 일반적으로 사용되는 스토리지 엔진으로, 빠른 속도와 작은 저장 공간이 장점입니다. 마이ISA

MySQL 스토리지 엔진 읽기 성능을 향상하기 위한 팁 및 전략: MyISAM과 InnoDB의 비교 분석 MySQL 스토리지 엔진 읽기 성능을 향상하기 위한 팁 및 전략: MyISAM과 InnoDB의 비교 분석 Jul 26, 2023 am 10:01 AM

MySQL 스토리지 엔진의 읽기 성능을 향상시키기 위한 팁 및 전략: MyISAM과 InnoDB의 비교 분석 소개: MySQL은 주로 대량의 구조화된 데이터를 저장하고 관리하는 데 사용되는 가장 일반적으로 사용되는 오픈 소스 관계형 데이터베이스 관리 시스템 중 하나입니다. 애플리케이션에서는 읽기 작업이 대부분의 애플리케이션에서 주요 작업 유형이기 때문에 데이터베이스의 읽기 성능이 매우 중요한 경우가 많습니다. 이 기사에서는 일반적으로 사용되는 두 가지 스토리지 엔진인 MyISAM과 InnoDB에 대한 비교 분석을 중심으로 MySQL 스토리지 엔진의 읽기 성능을 향상시키는 방법에 중점을 둘 것입니다.

Jul 24, 2023 pm 11:07 PM

GIS 데이터를 지원하는 MySQL 스토리지 엔진: InnoDB의 공간 인덱스 최적화 개요: 최신 데이터베이스 애플리케이션에서 지리 정보 시스템(GIS) 데이터는 점점 더 중요한 역할을 합니다. GIS 데이터 처리는 복잡하고 동적이며 기존 관계형 데이터베이스는 이러한 유형의 데이터를 처리하는 데 적합하지 않습니다. 그러나 MySQL은 GIS 데이터 처리를 최적화할 수 있는 스토리지 엔진인 InnoDB를 제공합니다. 이 기사에서는 InnoDB 스토리지 엔진에서 공간 인덱스를 사용하여 GIS 데이터를 최적화하는 방법을 소개합니다.

See all articles