From 4bbbb3810eb043af521dd60e738aaa2538cf30d4 Mon Sep 17 00:00:00 2001 From: Chris Hajas Date: Tue, 25 Aug 2020 09:26:21 -0400 Subject: [PATCH] Harden analyzedb further against dropped/recreated tables (#10669) Commit 445fc7c hardened some parts of analyzedb. However, it missed a couple of cases. 1) When the statement to get the modcount from the pg_aoseg table failed due to a dropped table, the transaction was also terminated. This caused further modcount queries to fail and while those tables were analyzed, it would error and not properly record the mod count. Therefore, we now restart the transaction when it errors. 2) If the table is dropped and then recreated while analyzedb is running (or some other mechanism that results in the table being successfully analyzed, but the pg_aoseg table did not exist during the initial check), the logic to update the modcount may fail. Now, we skip the update for the table if this occurs. In this case, the modcount would not be recorded and the next analyzedb run will consider the table modified (or dirty) and re-analyze it, which is the desired behavior. --- gpMgmt/bin/analyzedb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gpMgmt/bin/analyzedb b/gpMgmt/bin/analyzedb index f7dfbc947c..dd71c08d82 100755 --- a/gpMgmt/bin/analyzedb +++ b/gpMgmt/bin/analyzedb @@ -210,9 +210,13 @@ def get_partition_state_tuples(pg_port, dbname, catalog_schema, partition_info): modcount = dbconn.querySingleton(conn, modcount_sql) except pg.DatabaseError as e: if "does not exist" in str(e): - logger.debug("Table %s.%s (%s) no longer exists", schemaname, partition_name, tupletable) + logger.info("Table %s.%s (%s) no longer exists and will not be analyzed", schemaname, partition_name, tupletable) else: logger.error(str(e)) + if conn: + conn.close() + # If there's an exception, the transaction is closed so we need to reconnect + conn = dbconn.connect(dburl) else: num_sqls += 1 if num_sqls == 1000: # The choice of batch size was chosen arbitrarily @@ -683,8 +687,9 @@ class AnalyzeDb(Operation): for schema_table in (x for x in self.success_list if x not in heap_partitions and x not in root_partition_col_dict): # update modcount for tables that are successfully analyzed - new_modcount = curr_ao_state_dict[schema_table] - prev_ao_state_dict[schema_table] = new_modcount + if schema_table in curr_ao_state_dict: + new_modcount = curr_ao_state_dict[schema_table] + prev_ao_state_dict[schema_table] = new_modcount # update last op for tables that are successfully analyzed last_op_info = curr_last_op_dict[schema_table] # {'CREATE':'', 'ALTER':'', ...} -- GitLab