Issue
After clone completion Orphan records are observed in sys_connection table.
Release
All Release
Cause
In an out of box instance following is configuration
Exclude : sys_connection [ only base table and not child tables ]
Preserve : sys_connection [only base table and not child tables ]
Existing PRB1403259 [ Clone - Excluding base TPC table doesn't exclude child tables extending it] is FIXED on 28th May 2020
Due to which if base table is in Exclude configuration of the source instance, it will automatically exclude child tables too [ if it is TPC ( table per class ) table], in this example EXCLUDE was applied for [ sys_connection , jdbc_connection , http_connection ], BUT PRESERVE was only applied to [ sys_connection ].
Exclude Config
Preserve Config
Orphan records example :
Resolution
0. Script to find list of orphan records and table/class contributing to orphan records is following.
findOrphans('sys_connection', null, false);
// ============== WARNING ================ //
// Do not modify anything below this line! //
// ======================================= //
function findOrphans(table, query, remove) {
GlideTransaction.get().setAllowExcessiveLogging(true);
if (gs.getCurrentScopeName() != 'rhino.global') {
gs.info("This script must be run in the global scope. Please switch your scope and try again.");
return;
}
var orphanCount = 0, removedCount = 0;
var gr = new GlideRecord(table);
if (query !== null) {
gs.info("Querying " + table + " with encoded query: " + query);
gr.addEncodedQuery(query);
} else gs.info("Querying all rows on " + table);
gr.query();
gr.setWorkflow(false);
while(gr.next()) {
if(isOrphan(gr)) {
gs.info("Found orphan on " + table + " (Class: " + gr.sys_class_name + " - Sys ID: " + gr.sys_id + ")");
orphanCount++;
}
}
gs.info("Total orphans found: " + orphanCount);
}
function isOrphan(gr) {
if(gr.sys_class_name == null || gr.sys_class_name == '') return false;
var childClass = new GlideRecord(gr.sys_class_name);
if(!childClass.isValid()) return true;
childClass.get(gr.sys_id);
return !childClass.isValidRecord();
}
1. Cleanup of orphan records, navigate to Scripts - Background of the instance, and run following Script.
findOrphans('sys_connection', null, true); // ============== WARNING ================ // // Do not modify anything below this line! // // ======================================= // function findOrphans(table, query, remove) { if (gs.getCurrentScopeName() != 'rhino.global') { gs.info("This script must be run in the global scope. Please switch your scope and try again."); return; } var orphanCount = 0, removedCount = 0; var gr = new GlideRecord(table); if (query !== null) { gs.info("Querying " + table + " with encoded query: " + query); gr.addEncodedQuery(query); } else gs.info("Querying all rows on " + table); gr.query(); gr.setWorkflow(false); while(gr.next()) { if(isOrphan(gr)) { gs.info("Found orphan on " + table + " (Class: " + gr.sys_class_name + " - Sys ID: " + gr.sys_id + ")"); orphanCount++; if (remove === true) { gs.info("Removing orphan"); gr.sys_class_name = table; gr.update(); gr.deleteRecord(); removedCount++; } } } gs.info("Total orphans found: " + orphanCount); gs.info("Total orphans removed: " + removedCount); } function isOrphan(gr) { if(gr.sys_class_name == null || gr.sys_class_name == '') return false; var childClass = new GlideRecord(gr.sys_class_name); if(!childClass.isValid()) return true; childClass.get(gr.sys_id); return !childClass.isValidRecord(); }
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2. How to avoid this in the future?
Please manually add child tables in the Preserve configuration of the source instance.
In this example: Please add the following tables
++++++++++++++++++++++++++++++
- jdbc_connection
- http_connection
- orch_jms_ds
OR any other table which EXTENDS to sys_connection
Ho to create a Data Preserver ?