Skip to main content

在Azure Synpase Spark Pool中移动外部分区表数据到新位置后新建分区表发现丢失所有数据

分类:  Azure Synapse 标签:  #Azure #Trouble Shooting #大数据 发布于: 2025-02-19 13:20:17

最近在测试Azure Synapse Spark Pool的功能,发现如果在创建外部表的时候指定了分区,然后移动这个外部表到另外的位置,重建表,然后查询数据发现所有的数据都丢失。但是如果创建外部表时不指定分区,则没有这个问题。

重现的步骤如下:

  1. 创建一个Azure Synpase实例,然后创建一个Spark pool

  2. 创建一个外部表:

     CREATE DATABASE mytestdb;
     CREATE TABLE mytestdb.testtable1
     (id int, name string, birthdate date)
     USING Parquet
     LOCATION "abfss://synapse@testsynapse.dfs.core.chinacloudapi.cn/synapse/workspaces/testsynapse/warehouse/mytestdb.db/testtable1/"
    
    
  3. 然后给该表插入数据:

        INSERT INTO mytestdb.testtable1  values (1, 'mike01', cast('2003-09-26' as date)),
            (1, 'mike01', cast('2003-09-26' as date)),
            (1, 'mike01', cast('2003-09-26' as date)),
            (1, 'mike01', cast('2003-09-26' as date)),
            (1, 'mike01', cast('2003-09-26' as date)),
            (1, 'mike01', cast('2003-09-26' as date))
    

    查询该表的数据,确认数据都ok

  4. 使用工具, 例如Azure Storage Explorer将目录:/synapse/workspaces/testsynapse/warehouse/mytestdb.db/testtable1/ 移动到目录:另外一个容器data/testtable1, 然后重新创建外部表:

        -- Drop table first
        DROP TABLE mytestdb.testtable1;
        CREATE TABLE mytestdb.testtable1
        (id int, name string, birthdate date)
            USING Parquet
        LOCATION "abfss://data@testsynapse.dfs.core.chinacloudapi.cn/testtable1/"
    

    然后查询数据:

        SELECT * FROM mytestdb.testtable1
    

    发现数据都在的:




  5. 重新使用分区语句创建一个新表:

        CREATE TABLE mytestdb.testtable3
        (id int, name string, birthdate date)
        PARTITIONED BY (NAME2 STRING)
        STORED AS Parquet
        LOCATION "abfss://synapse@testsynapse.dfs.core.chinacloudapi.cn/synapse/workspaces/testsynapse/warehouse/mytestdb.db/testtable3/"
    

    并插入数据:

        INSERT INTO mytestdb.testtable3  values (1, 'mike01', cast('2003-09-26' as date), 'mike01'),
        (1, 'mike01', cast('2003-09-26' as date), 'mike01'),
        (1, 'mike01', cast('2003-09-26' as date), 'mike01'),
        (1, 'mike01', cast('2003-09-26' as date), 'mike01'),
        (1, 'mike01', cast('2003-09-26' as date), 'mike01'),
    

    插入完成后,使用查询语句SELECT * FROM mytestdb.testtable3 确认表数据都在。

  6. 使用Azure Stoarge Exploere工具将数据表目录synapse/workspaces/testsynapse/warehouse/mytestdb.db/testtable3/ 拷贝到容器:data 下的/testtable3

  7. 使用如下语句重新创建新表:

        CREATE TABLE mytestdb.testtable4
        (id int, name string, birthdate date)
        PARTITIONED BY (NAME2 STRING)
        STORED AS Parquet
        LOCATION "abfss://data@testsynapse.dfs.core.chinacloudapi.cn/testtable3/"
    

    创建完该表后,运行查询语句SELECT * FROM mytestdb.testtable4 发现虽然表目录下的文件都在,但是没有任何数据,检查Azure Stoarge下的目录,甚至是对比文件,所有的数据看起来都没有什么问题。

缓解办法

继续运行语句

MSCK REPAIR TABLE mytestdb.testtable4

然后再次运行查询语句:SELECT * FROM mytestdb.testtable4 可以看到数据恢复:



原因分析

将原有数据拷贝到一个新位置,然后在该位置使用现有数据重建该表,Meta Store完全没有了现有数据的分区相关的元数据,所以需要重建元数据。使用上述命令即可重新取得现有数据的分区元数据信息。