Todos os produtos
Search
Central de documentação

Elastic Compute Service:Create application-consistent snapshots for MySQL on Linux

Última atualização: Sep 22, 2026

Utilize uma instância CentOS 7.9 com MySQL 8.0 para criar e verificar snapshots consistentes com a aplicação, evitando a corrupção de dados durante o backup.

Pré-requisitos

  • A instância ECS usa ESSDs e o recurso multi-attach está desativado para os discos.

  • A instância ECS está no estado Running. O Cloud Assistant está no estado Normal na instância. visualize o status do Cloud Assistant. Consulte Check Cloud Assistant status and troubleshoot exceptions.

  • O MySQL está instalado e você possui o nome de usuário e a senha do banco de dados. Consulte Manually deploy a MySQL database (Linux).

  • A instância ECS deve ter uma função RAM com uma política personalizada para snapshots consistentes com a aplicação. Consulte Create a RAM role and attach it to an ECS instance.

    Nota

    O Cloud Assistant requer permissões específicas para acessar a instância ECS e executar comandos. Conceda essas permissões por meio da função RAM.

    • Configure uma função RAM personalizada, como AppSnapshotRoleName.

    • Anexe uma política personalizada à função RAM. A política de exemplo a seguir concede permissões para consultar snapshots, criar snapshots, adicionar tags e consultar informações de disco.

      {
          "Version": "1",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "ecs:DescribeSnapshot*",
                      "ecs:CreateSnapshot*",
                      "ecs:TagResources",
                      "ecs:DescribeDisks"
                  ],
                  "Resource": [
                      "*"
                  ],
                  "Condition": {}
              }
          ]
      }

Fluxo de trabalho

O fluxo de trabalho a seguir cria um snapshot consistente com a aplicação e verifica se o banco de dados retorna ao estado exato capturado no momento do snapshot:

image
  1. Step 1: Create the prescript.sh and postscript.sh scripts

    crie um prescript (prescript.sh) para pausar as gravações no banco de dados e um postscript (postscript.sh) para retomá-las. Esses scripts são obrigatórios para snapshots consistentes com a aplicação.

  2. Step 2: Prepare the database verification environment

    crie uma tabela de banco de dados e um procedimento armazenado (TestPIT) que simule gravações contínuas, para verificar a eficácia do snapshot após a reversão.

  3. Step 3: Create an application-consistent snapshot in the console

    crie um snapshot consistente com a aplicação para a instância Linux que hospeda o MySQL. O prescript e o postscript pausam e retomam temporariamente as gravações no banco de dados para garantir a consistência dos dados.

  4. Step 4: Verify that the application-consistent snapshot is created

    verifique os resultados da execução do comando do Cloud Assistant. Anote os horários de pausa e retomada do banco de dados.

  5. Step 5: Verify the data restoration from the application-consistent snapshot

    Reverta o disco usando o snapshot. Compare o horário da última gravação de dados no MySQL com o horário de execução do prescript.sh e verifique a restauração correta dos dados.

    • Se o horário da última gravação for anterior ao horário de execução do prescript, nenhuma gravação ocorreu durante a pausa. Os dados restaurados correspondem ao estado do snapshot.

    • Se o horário da última gravação for igual ou posterior ao horário de execução do prescript, ocorreram gravações durante a pausa, indicando que o snapshot não funcionou conforme o esperado.

Procedimento

Etapa 1: crie os scripts prescript.sh e postscript.sh

Importante

Os scripts prescript.sh e postscript.sh deste tópico são apenas para demonstração. Escreva os scripts com base nas necessidades reais do seu negócio. Consulte Create an application-consistent snapshot.

  1. Conecte-se à instância ECS como usuário root.

    Consulte Log on to a Linux instance using Workbench.

  2. crie o arquivo /tmp/prescript.sh e adicione o conteúdo do script.

    1. crie o arquivo /tmp/prescript.sh como root.

      vim /tmp/prescript.sh
    2. Pressione i e edite o arquivo.

    3. Personalize o conteúdo do prescript.sh para a sua aplicação.

      prescript.sh content

      TIMESTAMP=`date +%s`
      MYSQL_TEMP_FILE_NAME="/tmp/mysqlfreeze${TIMESTAMP}.tmp"
      LOG_FILE_NAME="/tmp/mysqlfreeze${TIMESTAMP}.log"
      
      # Set your MySQL username
      export MYSQL_USER="$MYSQL_USER"
      # Set your MySQL password
      export MYSQL_PWD="$MYSQL_PASSWORD"
      
      function Log()
      {
          echo "$1" 
          echo "$1" >> ${LOG_FILE_NAME}
      }
      
      function ExitWithResult()
      {
          Log "[INFO]:mysql freeze result is $1."
          exit $1
      }
      
      function Main()
      {
          Log "*********************************************************************"
          Log "[INFO]:Begin to freeze mysql."
      
          which mysql
          if [ $? -ne 0 ]
          then
              Log "[INFO]:mysql is not installed."
              ExitWithResult 0
          fi  
      
          systemctl status mysqld.service | grep "inactive (dead)"
          if [ $? -ne 1 ]
          then
              Log "[ERROR]:mysql is not running."
              ExitWithResult 0
          fi  
      
          mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "show processlist;" > "${MYSQL_TEMP_FILE_NAME}" 2>&1
          if [ $? -ne 0 ]
          then
              cat ${MYSQL_TEMP_FILE_NAME} >>"${LOG_FILE_NAME}"
              [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME}
              Log "[ERROR]:Show process list failed."
              ExitWithResult 1
          fi
      
          process_id=`cat ${MYSQL_TEMP_FILE_NAME} | grep "select 1 and sleep(25)" | awk -F " " '{print $1}'`
          if [ "$process_id" != "" ]
          then
              cat ${MYSQL_TEMP_FILE_NAME} >>"${LOG_FILE_NAME}"
              [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME}
              Log "[ERROR]:MySQL already been freezed "
              ExitWithResult 1
          fi
      
          cat ${MYSQL_TEMP_FILE_NAME}
      
          Log "[INFO]:Try to execute flush tables command"
      
             echo "flush tables with read lock;select 1 and sleep(25);" | nohup mysql -u$MYSQL_USER -p$MYSQL_PASSWORD >> "${LOG_FILE_NAME}" 2>&1 &
          if [ $? -ne 0 ]
          then
              Log "[ERROR]:Freeze mysql failed."
              ExitWithResult 1
          fi  
      
          Log "[INFO]:Flush tables command execute success"
      
          checkTime=0
          while [ 1 ]
          do
              mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "show processlist;" > "${MYSQL_TEMP_FILE_NAME}" 2>&1
              if [ $? -ne 0 ]
              then
                  cat ${MYSQL_TEMP_FILE_NAME} >>"${LOG_FILE_NAME}"
                  [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME}
                  Log "[ERROR]:Show process list failed."
                  ExitWithResult 1
              fi
              
              cat ${MYSQL_TEMP_FILE_NAME}
      
              process_id=`cat ${MYSQL_TEMP_FILE_NAME} | grep "select 1 and sleep(25)" | awk -F " " '{print $1}'`
              if [ "$process_id" = "" ]
              then
                  checkTime=`expr $checkTime + 1`
                  Log "[INFO]:Mysql is not freeze. checkTime is ${checkTime}"
                  sleep 1
              else
                  Log "[INFO]:Found sleep command in processlist,freeze success"
                  break
              fi
      
                 if [ $checkTime -eq 10 ]
              then
                  cat "${MYSQL_TEMP_FILE_NAME}" >>"${LOG_FILE_NAME}" 2>&1
                  
                  freeze_id=`cat ${MYSQL_TEMP_FILE_NAME} | grep "flush tables with read lock" | awk -F " " '{print $1}'`            
                  mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "kill $freeze_id;" >> "${LOG_FILE_NAME}" 2>&1
                  if [ $? -ne 0 ]
                  then
                      Log "[ERROR]:Thaw mysql failed."
                  fi    
      
                  [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME}
                  Log "[ERROR]:Mysql is not freeze. Will return error"
                  ExitWithResult 1
              fi
          done
      
             [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME}
          Log "[INFO]:Finish freeze mysql."
          ExitWithResult 0
      }
      Main

      Modifique os seguintes parâmetros:

      • $MYSQL_USER: seu nome de usuário do MySQL.

      • $MYSQL_PASSWORD: sua senha do MySQL.

    4. Pressione Esc, insira :wq e pressione Enter, salve e saia.

    5. defina as permissões como 700 (apenas root).

      Importante

      Apenas o usuário root deve ter permissões de leitura, gravação e execução (700). Caso contrário, a execução do script falhará.

      chmod 700 /tmp/prescript.sh
  3. crie o arquivo /tmp/postscript.sh e adicione o conteúdo do script.

    1. crie o arquivo /tmp/postscript.sh como root.

      vim /tmp/postscript.sh
    2. Pressione i e edite o arquivo.

    3. Personalize o conteúdo do postscript.sh para a sua aplicação.

      postscript.sh content

      TIMESTAMP=`date +%s`
      MYSQL_TEMP_FILE_NAME="/tmp/mysqlthaw${TIMESTAMP}.tmp"
      LOG_FILE_NAME="/tmp/mysqlthaw${TIMESTAMP}.log"
      # Set your MySQL username
      export MYSQL_USER="$MYSQL_USER"
      # Set your MySQL password
      export MYSQL_PWD="$MYSQL_PASSWORD"
      
      function Log()
      {
          echo "$1" 
          echo "$1" >> ${LOG_FILE_NAME}
      }
      
      function ExitWithResult()
      {
          Log "[INFO]:mysql unfreeze result is $1."
          exit $1
      }
      
      function Main()
      {
          Log "*********************************************************************"
          Log "[INFO]:Begin to thaw mysql."   
      
          which mysql
          if [ $? -ne 0 ]
          then
              Log "[INFO]:mysql is not installed."
              ExitWithResult 0
          fi  
      
          systemctl status mysqld.service | grep "inactive (dead)"
          if [ $? -ne 1 ]
          then
              Log "[ERROR]:mysql is not running."
              ExitWithResult 0
          fi  
      
          mysql -u$MYSQL_USER  -e "show processlist;" > "${MYSQL_TEMP_FILE_NAME}" 2>&1
          if [ $? -ne 0 ]
          then
              cat ${MYSQL_TEMP_FILE_NAME} >>"${LOG_FILE_NAME}"
              [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME}
              Log "[ERROR]:show process list failed."
              ExitWithResult 1
          fi
      
          Log "[INFO]:show process list success."
      
          cat ${MYSQL_TEMP_FILE_NAME}
          
          process_ids=`cat ${MYSQL_TEMP_FILE_NAME} | grep "select 1 and sleep(25)" | awk -F " " '{print $1}'`
          if [ "$process_ids" = "" ]
          then
              [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME}
              Log "[ERROR]:Get freeze process_id failed."
              ExitWithResult 1
          fi
      
          cat ${MYSQL_TEMP_FILE_NAME} | grep "select 1 and sleep(25)" | awk -F " " '{print $1}'| while read pid
          do
              Log "[INFO]:Try to stop sql process ${pid}."
      
              mysql -u$MYSQL_USER  -e "kill $pid;" >> "${LOG_FILE_NAME}" 2>&1
              if [ $? -ne 0 ]
              then
                  [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME}
                  Log "[ERROR]:Thaw mysql failed.PIDs is ${process_ids}"
                  ExitWithResult 1
              fi   
              Log "[INFO]:Stop sql process ${pid} success."
      
          done 
          
          [ -f ${MYSQL_TEMP_FILE_NAME} ] && rm -rf ${MYSQL_TEMP_FILE_NAME}
          Log "[INFO]:Finish thaw mysql."
          ExitWithResult 0
      }
      Main

      Modifique os seguintes parâmetros:

      • $MYSQL_USER: seu nome de usuário do MySQL.

      • $MYSQL_PASSWORD: sua senha do MySQL.

    4. Pressione Esc, insira :wq e pressione Enter, salve e saia.

    5. defina as permissões como 700 (apenas root).

      Importante

      Apenas o usuário root deve ter permissões de leitura, gravação e execução (700). Caso contrário, a execução do script falhará.

      chmod 700 /tmp/postscript.sh
  4. acesse o diretório /tmp e verifique as permissões do script.

    cd /tmp
    ls -l

    A saída a seguir mostra as permissões corretas.

    image

Etapa 2: Preparar o ambiente de verificação do banco de dados

  1. crie o script de teste /root/test.sql.

    1. crie e abra o arquivo /root/test.sql.

      vim /root/test.sql
    2. Pressione i e edite o arquivo.

    3. Adicione o script SQL de verificação.

      O script cria uma tabela (PointInTime) e um procedimento armazenado (TestPIT):

      USE AdventureWorks;
      CREATE TABLE PointInTime(id int, t datetime);
      DELIMITER $$
      CREATE PROCEDURE `TestPIT`()
      BEGIN
      DECLARE i int;
      SET i=1;
      WHILE i < 180
      DO
      INSERT INTO PointInTime VALUES(i, now());
      SELECT SLEEP(1);
      SET i=i+1;
      END WHILE;
      END $$
      DELIMITER ;
    4. Pressione Esc, insira :wq e pressione Enter, salve e saia.

  2. Conecte-se ao MySQL.

    execute o comando a seguir e insira a senha do MySQL quando solicitado.

    mysql -u <mysqlUserName> -p

    Substitua <mysqlUserName> pelo seu nome de usuário do MySQL.

  3. crie um banco de dados chamado AdventureWorks.

    CREATE DATABASE AdventureWorks;
  4. execute o script de teste.

    source /root/test.sql
  5. Chame o procedimento armazenado (TestPIT).

    CALL TestPIT;
    Importante

    crie o snapshot consistente com a aplicação antes que o TestPIT termine. O procedimento é executado por cerca de 3 minutos.

Etapa 3: Criar um snapshot consistente com a aplicação no console

  1. acesse o console do ECS - grupo de consistência de snapshot.

  2. No canto superior esquerdo da página, selecione uma região e um grupo de recursos.

  3. Na guia Snapshot-consistent Groups, clique em Create Snapshot-consistent Group.

  4. Na caixa de diálogo Create Snapshot, configure o grupo de consistência de snapshot.

    1. Resource Types tem como padrão Instance.

    2. selecione a instância e seus discos ESSD.

    3. Expanda Advanced Settings e ative o snapshot consistente com a aplicação.

      1. selecione Enable Application-consistent Snapshot.

      2. defina os caminhos do prescript.sh e do postscript.sh para os scripts criados em Step 1.

      3. defina a duração para File System I/O Pause and Resume.

  5. clique em OK.

    O comando retorna um ID de execução do Cloud Assistant. Use este ID e visualize o resultado da execução.

Etapa 4: Verificar se o snapshot consistente com a aplicação foi criado

  1. clique em ID de execução do Cloud Assistant e visualize o resultado.

    image

    Um Exit Code igual a 0 indica a criação bem-sucedida do snapshot. A saída exibe os IDs do snapshot e do grupo de consistência de snapshot.

    Nota

    Se o Exit Code não for 0, solucione o problema com base no código de erro do Exit Code. Consulte Error codes.

  2. visualize os horários de pausa e retomada do banco de dados na saída do Cloud Assistant.

    Encontre o horário de início do prescript.sh e o horário de conclusão do postscript.sh.

    • O prescript.sh foi executado às 2024-08-27 15:27:55, indicando que o banco de dados pausou as gravações neste horário.image

    • O postscript.sh foi executado às 2024-08-27 15:27:57, indicando que o banco de dados retomou as gravações neste horário.

      image

  3. visualize o grupo de consistência de snapshot e o snapshot de disco.

    1. acesse o console do ECS - grupo de consistência de snapshot.

    2. Na guia Snapshot-consistent Groups, clique em ID do grupo de consistência de snapshot e visualize os detalhes.

    3. Na seção Snapshot Information, verifique se a tag do snapshot confirma a consistência da aplicação.

      A tag APPConsistent:True do snapshot de disco confirma a criação de um snapshot consistente com a aplicação.

      image

  4. Conecte-se ao MySQL e verifique o horário de pausa do commit de dados.

    1. Conecte-se à instância ECS.

      Consulte Log on to a Linux instance using Workbench.

    2. Conecte-se ao MySQL.

      execute o comando a seguir e insira a senha do MySQL quando solicitado.

      mysql -u <mysqlUserName> -p

      Substitua <mysqlUserName> pelo seu nome de usuário do MySQL.

    3. Consulte a tabela PointInTime.

      USE AdventureWorks;
      SELECT * FROM PointInTime;
    4. visualize o horário de pausa do banco de dados nos resultados da consulta.

      Nenhum dado foi inserido entre 2024-08-27 15:27:55 e 2024-08-27 15:27:58.

      image

Etapa 5: Verificar a restauração de dados a partir do snapshot consistente com a aplicação

  1. Reverta o disco usando o grupo de consistência de snapshot.

  2. Conecte-se ao MySQL e consulte a tabela PointInTime.

    1. Conecte-se à instância ECS.

      Consulte Log on to a Linux instance using Workbench.

    2. Conecte-se ao MySQL.

      execute o comando a seguir e insira a senha do MySQL quando solicitado.

      mysql -u <mysqlUserName> -p

      Substitua <mysqlUserName> pelo seu nome de usuário do MySQL.

    3. Consulte a tabela PointInTime.

      USE AdventureWorks;
      SELECT * FROM PointInTime;
    4. visualize o timestamp do último registro após a restauração dos dados.

      O último registro foi inserido às 2024-08-27 15:27:54, anterior ao horário de pausa 2024-08-27 15:27:55 registrado em Step 4. Isso confirma a restauração correta dos dados a partir do snapshot consistente com a aplicação.

      image