MySQL의 update 문이 어떻게 실행되는지 분석해 보겠습니다.

WBOY
풀어 주다: 2022-03-31 12:08:16
앞으로
2752명이 탐색했습니다.

이 글에서는 mysql에 대한 관련 지식을 제공합니다. 업데이트 문이 실행되는 방식과 관련된 문제를 주로 소개합니다. 업데이트 작업이 실행되면 테이블과 관련된 쿼리 캐시가 유효하지 않게 되므로 문이 모든 캐시된 결과를 얻습니다. on the table이 정리될 것입니다. 모두에게 도움이 되기를 바랍니다.

MySQL의 update 문이 어떻게 실행되는지 분석해 보겠습니다.

추천 학습: mysql tutorial

사전 준비

먼저 테이블을 생성하고 세 가지 데이터를 삽입하세요:

CREATE TABLE T(
	ID int(11) NOT NULL AUTO_INCREMENT,
	c int(11) NOT NULL,
	PRIMARY KEY (ID)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='测试表';INSERT INTO T(c) VALUES (1), (2), (3);
로그인 후 복사

업데이트 작업은 나중에 수행하겠습니다:

update T set c=c+1 where ID=2;
로그인 후 복사
로그인 후 복사
로그인 후 복사

업데이트 작업에 대해 이야기하기 전에 , 모두가 먼저입니다 MySQL에서 SQL 문의 실행 과정을 살펴보세요~

SQL 문의 실행 과정

MySQL의 update 문이 어떻게 실행되는지 분석해 보겠습니다.

그림에서 볼 수 있듯이 MySQL 데이터베이스는 크게 서비스 계층과 2가지 수준으로 나뉩니다. 스토리지 엔진 레이어 서비스 레이어: 서버 레이어에는 MySQL의 대부분의 핵심 기능을 포함하여 커넥터, 쿼리 캐시, 분석기, 실행기가 포함됩니다. 저장 프로시저를 포함한 모든 교차 스토리지 엔진 기능도 이 레이어에 구현됩니다. 트리거, 뷰 등 스토리지 엔진 계층: 스토리지 엔진 계층에는 MyISAM, InnoDB 및 Memory를 비롯한 일반적인 MySQL 스토리지 엔진이 포함되어 있으며, 가장 일반적으로 사용되는 것은 MySQL의 기본 스토리지 엔진이기도 한 InnoDB입니다.

서버 계층의 구성 요소 소개

  • 커넥터: MySQL 클라이언트 로그인이 필요하며, 사용자와 MySQL 데이터베이스를 연결하려면 커넥터가 필요합니다. MySQL 로그인에는 "mysql -u 사용자 이름 -p 비밀번호", TCP 핸드셰이크가 완료된 후 커넥터는 입력된 사용자 이름과 비밀번호를 기반으로 로그인을 인증합니다.

  • 쿼리 캐시: MySQL은 실행 요청을 받은 후 먼저 쿼리 캐시에서 이 SQL 문이 이전에 실행되었는지 확인합니다. 이전에 실행된 문과 결과는 키-값 형식으로 저장됩니다. 쌍. 키는 쿼리 문이고 값은 쿼리 결과입니다. 해당 SQL 문을 키를 통해 찾을 수 있으면 SQL 실행 결과가 바로 반환됩니다. 캐시에 없으면 후속 실행 단계가 계속됩니다. 실행이 완료된 후 실행 결과는 쿼리 캐시에 저장됩니다. 장점은 효율성이 높다는 것입니다. 그러나 MySQL에서 특정 테이블이 업데이트되면 모든 쿼리 캐시가 무효화되므로 쿼리 캐시 사용은 권장되지 않습니다. 자주 업데이트되는 데이터베이스의 경우 쿼리 캐시 적중률이 매우 낮습니다. 참고: MySQL 버전 8.0에서는 쿼리 캐시 기능이 삭제되어 쿼리 캐시 기능이 없습니다.

  • Analyzer: 어휘 분석과 구문 분석으로 나누어집니다

    • 어휘 분석: 먼저, MySQL 분석기는 먼저 어휘 분석을 수행합니다. 작성하는 SQL은 여러 문자열과 공백으로 구성된 SQL 문으로, 문자열이 무엇인지, 무엇을 나타내는지 식별해야 합니다.
    • 문법 분석: 그런 다음 어휘 분석 결과를 바탕으로 구문 분석기는 입력된 SQL 문이 문법 규칙에 따라 MySQL 구문을 만족하는지 여부를 판단합니다. SQL 문이 잘못된 경우 다음 메시지가 표시됩니다. SQL suntax

  • 최적화 프로그램: 분석기로 분석한 후에는 SQL이 합법적이지만 실행하기 전에 최적화 프로그램에서 run 처리를 위해 최적화 프로그램은 사용할 인덱스와 사용할 연결을 결정합니다. 최적화 프로그램의 역할은 가장 효율적인 실행 계획을 결정하는 것입니다.

  • Executor:

    실행 단계에서 MySQL은 먼저 명령문을 실행할 권한이 있는지 확인합니다. 권한이 있으면 권한 없음 오류가 반환되고 테이블이 열립니다. 실행을 계속합니다. 테이블이 열리면 실행자는 엔진 정의에 따라 대상 엔진에서 제공하는 인터페이스를 사용합니다. 인덱스가 있는 테이블의 경우 실행 논리는 비슷합니다.

  • SQL 문의 실행 과정을 이해한 후 위의
이 어떻게 실행되는지 자세히 분석해 보겠습니다.

update T set c=c+1 where ID=2;Update 문 분석

update T set c=c+1 where ID=2;
로그인 후 복사
로그인 후 복사
로그인 후 복사

update

작업을 실행하면 이 테이블과 관련된 쿼리 캐시가 무효화되므로 이 문은 테이블 T에 캐시된 모든 결과를 지웁니다. 다음으로 분석기는 이것이 업데이트 문이라는 것을 알고 나면 어떤 인덱스를 사용할지 결정하고 실행기는 먼저 해당 행을 찾아 업데이트합니다. .

우리의 평소 생각에 따르면 이 레코드를 찾아 값을 변경하고 저장합니다. 하지만 세부적으로 살펴보면 데이터 수정이 포함되므로 로그도 포함됩니다. 업데이트 작업에는 두 가지 중요한 로그 모듈이 포함됩니다. redo 로그(redo 로그), bin 로그(아카이브 로그). MySQL의 이 두 로그도 꼭 배워야 합니다. redo log(重做日志)bin log(归档日志)。MySQL中的这两个日志也是必学的。

redo log(重做日志)

  • 在 MySQL 里,如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高。
    MySQL里使用WAL(预写式日志)技术,WAL 的全称是 Write-Ahead Logging,它的关键点就是 先写日志,再写磁盘
  • 具体来说,当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做。
  • InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB,那么总共就可以记录 4GB 的操作。从头开始写,写到末尾就又回到开头循环写。

听完上面对redo log日志的介绍后,小伙伴们可能会问:redo log日志存储在哪?数据库信息保存在磁盘上,redo log日志也保存在磁盘上,为什么要先写到redo log中再写到数据库中呢?redo log日志如果存满数据了怎么办?

redo 로그(redo log)
  • MySQL에서 모든 업데이트 작업을 디스크에 기록해야 하는 경우 디스크도 해당 레코드를 찾아 업데이트해야 합니다. 비용과 검색 비용이 모두 매우 높습니다.

MySQL은 WAL(미리 쓰기 로깅) 기술을 사용합니다. WAL의 전체 이름은 Write-Ahead Logging입니다. 핵심은

로그를 먼저 작성하고, 그런 다음 디스크에 쓰기

.
  • 구체적으로, 레코드를 업데이트해야 하는 경우 InnoDB 엔진은 먼저 해당 레코드를 리두 로그에 기록하고 메모리를 업데이트합니다. 이때 업데이트가 완료됩니다. 동시에 InnoDB 엔진은 적절한 시간에 디스크에 작업 기록을 업데이트하며, 이 업데이트는 시스템이 상대적으로 유휴 상태일 때 수행되는 경우가 많습니다.
  • InnoDB의 redo 로그는 고정된 크기를 가지고 있습니다. 예를 들어 4개의 파일로 구성할 수 있으며 각 파일의 크기는 1GB이며 총 4GB의 작업을 기록할 수 있습니다. 처음부터 쓰기 시작해서 끝까지 쓴 다음 처음으로 돌아가서 루프를 작성합니다.
  • 위의 리두 로그 소개를 듣고 친구들은 다음과 같이 질문할 수 있습니다. 리두 로그는 어디에 저장되어 있나요? , 데이터베이스 정보는 디스크에 저장되고, 리두 로그도 디스크에 저장됩니다. 왜 먼저 리두 로그에 기록한 다음 데이터베이스에 기록해야 할까요? , 리두 로그에 데이터가 가득 차면 어떻게 해야 하나요? 잠깐만요. 다음에는 이러한 질문에 답해 보겠습니다.

    리두 로그는 어디에 저장되나요?

    InnoDB 엔진은 먼저 Redo 로그에 레코드를 기록합니다. 이 역시 디스크에 기록하는 과정이지만 업데이트 과정과 다른 점은 다음과 같습니다. 업데이트 프로세스는 디스크에서 무작위 IO이므로 시간이 많이 걸립니다. 리두 로그를 작성하는 것은 디스크에 대한 순차적 IO입니다. 효율적이세요.
    MySQL의 update 문이 어떻게 실행되는지 분석해 보겠습니다.

    redo 로그 공간이 고정되어 있는데, 다 없어지나요?

    우선, 리두 로그는 재활용되므로 공간이 부족할까봐 걱정하지 마세요. 예를 들어, 리두 로그 로그는 4개의 파일 세트로 구성되며 각 파일은 1G입니다. 작성 과정은 다음과 같습니다.

    간단한 요약: redo 로그는 Innodb 스토리지 엔진의 고유한 메커니즘으로 비정상적인 복구

    ,

    Crash-safe, redo를 처리하는 데 사용할 수 있습니다. mysql이 비정상적으로 다시 시작되도록 보장할 수 있습니다. 이 경우 커밋되지 않은 트랜잭션은 롤백되고 제출된 트랜잭션은 데이터베이스에 안전하게 삭제됩니다.

    crash-safe:
    InnoDB는 데이터베이스가 비정상적으로 다시 시작되더라도 이전에 제출된 레코드가 손실되지 않도록 보장할 수 있습니다. 이 기능을 crash-safe라고 합니다.

    🎜binlog (아카이브 로그)🎜🎜🎜redo 로그는 innoDB 엔진 고유의 로그입니다. Binlog는 mysql 서버 계층의 로그입니다. 🎜🎜🎜사실 bin 로그는 redo 로그보다 먼저 나타났습니다. 왜냐하면 처음에는 MySQL에 InnoDB 스토리지 엔진이 없었고 5.5 이전에는 MyISAM이었기 때문입니다. 그러나 MyISAM에는 충돌 방지 기능이 없으며 binlog 로그는 보관에만 사용할 수 있습니다. InnoDB는 다른 회사에서 플러그인 형태로 MySQL에 도입했습니다. binlog에만 의존하면 충돌 방지 기능이 없으므로 InnoDB는 충돌 방지 기능을 달성하기 위해 다른 로그 시스템, 즉 redo 로그를 사용합니다. 🎜

    redo logbin log的总结

    • redo log是为了保证innoDB引擎的crash-safe能力,也就是说在mysql异常宕机重启的时候,之前提交的事务可以保证不丢失;(因为成功提交的事务肯定是写入了redo log,可以从redo log恢复)
    • bin log是归档日志,将每个更新操作都追加到日志中。这样当需要将日志恢复到某个时间点的时候,就可以根据全量备份+bin log重放实现。 如果没有开启binlog,那么数据只能恢复到全量备份的时间点,而不能恢复到任意时间点。如果连全量备份也没做,mysql宕机,磁盘也坏了,那就很尴尬了。。

    redo logbin log的区别:

    • redo log 是 InnoDB 引擎特有的;bin log 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
    • redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;bin log 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
    • redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

    InnoDB引擎部分在执行这个简单的update语句的时候的内部流程

    update T set c=c+1 where ID=2;
    로그인 후 복사
    로그인 후 복사
    로그인 후 복사

    MySQL의 update 문이 어떻게 실행되는지 분석해 보겠습니다.

    手动用begin开启事务,然后执行update语句,再然后执行commit语句,那上面的update更新流程之前 哪些是update语句执行之后做的,哪些是commit语句执行之后做的?

    事实上,redo log在内存中有一个redo log buffer,binlog 也有一个binlog cache.所以在手动开启的事务中,你执行sql语句,其实是写到redo log bufferbinlog cache中去的(肯定不可能是直接写磁盘日志,一个是性能差一个是回滚的时候不可能去回滚磁盘日志吧),然后当你执行commit的时候,首先要将redo log的提交状态游prepare改为commit状态,然后就要把binlog cache刷新到binlog日志(可能也只是flush到操作系统的page cache,这个就看你的mysql配置),redo log buffer刷新到redo log 日志(刷新时机也是可以配置的)。 如果你回滚的话,就只用把binlog cacheredo log buffer中的数据清除就行了。

    在update过程中,mysql突然宕机,会发生什么情况?

    • 如果redolog写入了,处于prepare状态,binlog还没写入,那么宕机重启后,redolog中的这个事务就直接回滚了。

    • 如果redolog写入了,binlog也写入了,但redolog还没有更新为commit状态,那么宕机重启以后,mysql会去检查对应事务在binlog中是否完整。如果是,就提交事务;如果不是,就回滚事务。 (redolog处于prepare状态,binlog完整启动时就提交事务,为啥要这么设计? 主要是因为binlog写入了,那么就会被从库或者用这个binlog恢复出来的库使用,为了数据一致性就采用了这个策略)
      redo log和binlog是通过xid这个字段关联起来的。

    推荐学习:mysql教程

    위 내용은 MySQL의 update 문이 어떻게 실행되는지 분석해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    관련 라벨:
    원천:csdn.net
    본 웹사이트의 성명
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
    인기 튜토리얼
    더>
    최신 다운로드
    더>
    웹 효과
    웹사이트 소스 코드
    웹사이트 자료
    프론트엔드 템플릿