Restore

Let's take a deeper look at restoring data with GRAX.

Introduction

There are 2 main ways to restore data with GRAX:

Point-in-Time Restore allows you to update existing Salesforce records back to a selected point in time, and additionally select which specific fields you want to roll back for the chosen records.

Alternatively, GRAX Restore, the focus of this guide, allows you to restore any archived or deleted record(s) along with any child objects that you choose. This gives you the ability to visualize the entire hierarchy graph of records. Since this restore only inserts one object at a time back into Salesforce, it gives you the flexibility to insert one or more records for an object, address any validations or other issues that come up, and then decide which child object to insert next. Let's walk through how this works.

How to Seed a Restore

There are 3 main places from which you can kick off a GRAX Restore:

GRAX Record Page

You can arrive at the GRAX Record View via several different avenues, whether it be clicking into a record via the Execution viewer, or doing basic or advanced searches to find a specific record. Once you are on a record page, you will see a Restore button if GRAX has identified the record as either deleted or archived. Click this button will launch the restore flow for this specific record (along with building the entire hierarchy beneath the record in question, in case you end up wanting to restore children in subsequent single object restore jobs; don't worry we'll take a look exactly how this works in a bit).

Screen Shot 2022-03-02 at 10.32.33 AM.pngScreen Shot 2022-03-02 at 10.32.33 AM.png

Remember!

GRAX differentiates between a deleted record (manually deleted by user in Salesforce and captured by GRAX through automated delete tracking job) and an archived record (deleted via a GRAX archive job).

A Delete Source of grax indicates this record was captured as deleted via a GRAX archive job

A Delete Source of salesforce indicates this record was captured as deleted via the GRAX Delete Tracking functionality.

Archive Execution

If you go to the "Executions" tab and click into any Archive job, you should see a Restore button at the top of the page. Clicking this will kick off the restore flow, specifically for the top-level parent object.

Screen Shot 2022-03-02 at 10.22.39 AM.pngScreen Shot 2022-03-02 at 10.22.39 AM.png

Screen Shot 2022-03-02 at 10.22.55 AM.pngScreen Shot 2022-03-02 at 10.22.55 AM.png

Clicking Restore would bring you into the restore flow, allowing you to begin with a single object restore of Cases in this scenario since Case was the top-level object that we selected in our archive.

Advanced Search

If you perform an Advanced Search, and be sure to filter by a Status of archived or deleted, then the search results will offer a Restore button as well.

Screen Shot 2022-03-02 at 10.33.44 AM.pngScreen Shot 2022-03-02 at 10.33.44 AM.png
Filter your search by archived or deleted records, and then you will see a restore button appear when you check off 1 or more records in the results view.

How to Perform a Restore

Now that we've seen the different ways to launch a restore, let's take a look at what the process looks like when restoring data. We'll take a look at a couple of sample scenarios to make this real and convey the different considerations.

Restore a Single Case and Child Objects

In the archive execution example above, you can see we've archived 4 cases. Let's navigate to one of those Cases and see what we notice.

Screen Shot 2022-03-02 at 10.37.15 AM.pngScreen Shot 2022-03-02 at 10.37.15 AM.png
We can see on the record view page, there is a Restore button available. We can also easily navigate the hierarchy and drill into specific children if we wanted.

When you click Restore, GRAX will begin taking a snapshot of the entire hierarchy for this Case: every record on every object below the Case that is stored in GRAX. Typically this only takes a few seconds since we're only talking about 1 Case. But as we'll see later, if you tried to restore 1000 Cases, for example, GRAX would load the full hierarchy of all 1000 cases; this can take some time but don't worry you won't have to wait and watch as you'll be able to navigate away and come back when the processing of the hierarchy snapshot is done.

Screen Shot 2022-03-02 at 10.41.10 AM.pngScreen Shot 2022-03-02 at 10.41.10 AM.png
GRAX has successfully loaded the Case and all its children. You can click any object node to explore the hierarchy, though as you'll see this specific restore job is only for the Case.

Screen Shot 2022-03-02 at 10.45.45 AM.pngScreen Shot 2022-03-02 at 10.45.45 AM.png
I can click on an individual node in the hierarchy to see only the records for that object, and also then have the ability to Download a CSV of the IDs.

Skipped Records

You'll notice that all the other objects/records (besides Case) are greyed out and Skipped. This is because this is a single object restore, as you'll see. Each restore execution is only for 1 object. The entire hierarchy is snapshotted here so that you can do multiple single object restore executions to bring back just a part of the hierarchy or the entire hierarchy if you need.

You may also see a record tagged as Skipped for other reasons, for example Salesforce may not allow insertion of it. You'll see this with certain FeedItems that Salesforce auto-creates and does not allow you to insert.

We can use this restore preview page to confirm the records we want to restore are indeed here, and also start planning for future restores based on this hierarchy snapshot. Once we're confident, we can click Restore.

Once you confirm and execute the restore, you will be brought to the Restore Execution page. This page will give you a real-time update of the restore job.

Screen Shot 2022-03-02 at 10.47.13 AM.pngScreen Shot 2022-03-02 at 10.47.13 AM.png
We can see the 1 Case we wanted to restore is in progress.

Here are the various Restore Statuses you may see:

Restore StatusDescription
PendingA restore job is officially pending once you click restore and GRAX begin loading the hierarchy snapshot. This allows you to navigate away if needed as GRAX loads the full hierarchy of data.
ReadyOnce GRAX has finished loading the full hierarchy of data for the selected record(s) you chose to restore, the restore job will become ready. This means you are officially ready to preview the records and hierarchy snapshot and kick off the restore.
QueuedYou can only have 1 restore running at a time, so if you see this Status it means the restore job is waiting on another to finish first.
StartedThis is an active restore where GRAX is inserting data into Salesforce.
Post ProcessingAfter GRAX attempts the insert of all records for the object, you will notice that GRAX then takes an automatic backup of the records. This is necessary in order to capture a backup of the NEW Salesforce IDs that were just inserted. As you'll see when you navigate around the GRAX application, the old ID and new IDs of archived/restored records are mapped and linked so you can view the full history timeline of a record.
CompletedThe restore has successfully completed.
ErrorThe restore completed, but there were errors. You'll see details of the errors on the restore execution page. You can address the errors and retry if needed.

We can see that our single object restore of the single case has completed.

Screen Shot 2022-03-02 at 10.55.46 AM.pngScreen Shot 2022-03-02 at 10.55.46 AM.png

Now if we navigate to the Case record page, we'll see the new Salesforce ID and have the ability to view this record directly in Salesforce, but we can also use the version viewer to explore all versions, including the older archived version of this Case which had a different Salesforce ID. Pretty neat!

Screen Shot 2022-03-02 at 10.56.32 AM.pngScreen Shot 2022-03-02 at 10.56.32 AM.png

But what if we now want to restore all the Case Comments that were related to this Case? Well let's go back to the restore execution page.

Screen Shot 2022-03-02 at 10.58.20 AM.pngScreen Shot 2022-03-02 at 10.58.20 AM.png
After we saw our Case restore complete, we can click on another node such as Case Comment and launch another restore for ALL the Case Comments related to the Case.

Screen Shot 2022-03-02 at 10.59.17 AM.pngScreen Shot 2022-03-02 at 10.59.17 AM.png
We've launched another restore execution that will, as we can see, restore 2 Case Comments and link them to the Case that was just previously restored.

Screen Shot 2022-03-02 at 11.01.57 AM.pngScreen Shot 2022-03-02 at 11.01.57 AM.png
The restore execution for CaseComment has completed and we can see both records were Successful.

We can continue rinsing and repeating for any other objects that are in the hierarchy snapshot. While this is a small sample size, you can see how flexible and powerful this can be if you want to bring deleted or archived data back into Salesforce, along with the child records.

Restore Multiple Cases and Child Objects

Now that we've seen how to restore a single case that was part of our archive, along with its child objects, let's take a quick look at how to do essentially the same restore process but for multiple cases.

Screen Shot 2022-03-02 at 11.05.37 AM.pngScreen Shot 2022-03-02 at 11.05.37 AM.png
Let's first do an Advanced Search of all archived cases that were recently created. We see the 4 Cases that were part of our archive job. We'll go ahead and select a few of them and click Restore.

Screen Shot 2022-03-02 at 11.07.24 AM.pngScreen Shot 2022-03-02 at 11.07.24 AM.png
The restore preview flow launched and loads a snapshot of the hierarchy for the 3 selected cases. We can explore the hierarchy and when we're ready click Restore to kick off the restore of the 3 cases.

Screen Shot 2022-03-02 at 11.10.53 AM.pngScreen Shot 2022-03-02 at 11.10.53 AM.png
The 3 cases were successfully restored. We can now click into other child objects and launch restore executions for them as needed.

What is the correct order of objects to restore?

In the example above, we knew we wanted to start by restoring Cases, and then use the hierarchy snapshot to restore one child object at a time after that. But which object should we pick and in which order? That is a question that each Admin performing the restore will need to answer based on their unique Salesforce schema and business needs. The restore is a simple insert of data so if it can be inserted and the parent records already exist in Salesforce, it will succeed. For example, you won't restore Level 2 children before restoring Level 1 because most likely those Level 1 parents have to be restored and exist in Salesforce before the Level 2 children can be attempted.

Restore Tab

You can find a list of all restore executions by using the Restore tab. Let's take a look at how this overview tab is organized. At the the very top of the page, you'll see any pending or ready restores. As mentioned previously in this guide, it can sometimes take a longer time to load the entire hierarchy for a large set of data. Rather than waiting while it loads, you'll see a message that says you're able to navigate away and return to the Restore tab at a later tab and kick off the restore when it's ready.

Below this you'll see a list of all in progress or completed restores.

Screen Shot 2022-03-02 at 11.08.54 AM.pngScreen Shot 2022-03-02 at 11.08.54 AM.png
In this example, we can see we have 1 restore execution that is pending. This means GRAX is still loading the hierarchy snapshot for all the data. We also have 1 restore that is ready. This means the records have finished loading and you're free to go into the restore and kick it off.

Note on Restoring Files

When we refer to "Files" here we are referring to the interconnections between ContentDocument, ContentVersion, and ContentDocumentLink. GRAX automatically backs up all three of these objects when you do a File backup or an archive. But when restoring this data, there are plenty of Salesforce rules and limitations to be aware of. Here is the best way to go about restoring these Content objects, given that you'll need to do a series of single object restore executions:

  1. First, select the ContentDocument node in the hierarchy graph. Even though Salesforce does not actually support API inserts of the ContentDocument object, this is the object GRAX will use in the interface to represent "Files".

  2. Perform your restore of the ContentDocument(s) in question. When you kick off this restore, what's really happening is that GRAX is inserting a new ContentVersion record (this object contains the actual file binary), and then Salesforce auto-creates the ContentDocument for the ContentVersion. The post-processing backup step within the restore will capture the new IDs of both the ContentDocument and ContentVersion.

  3. As this point you have inserted the File back into Salesforce. However, it will technically be "orphaned" as it won't link to any records at this point. You need to restore the ContentDocumentLink records to establish the linkage between the ContentDocument and any other records (Account, Case, User, custom object etc). So from the restore execution page, select ContentDocumentLink and restore those records.

Common File Errors

Typically when restoring ContentDocumentLinks at this stage you may get an error such as:

code=INSUFFICIENT_ACCESS_OR_READONLY msg=Invalid sharing type I

This is relatively common due to the way Salesforce treats ContentDocumentLink sharing. The ContentDocumentLink may have been backed up with a certain Sharing Type but that Sharing Type cannot be set when inserting the ContentDocumentLink. Reach out to GRAX if this becomes an issue.

Other errors you may see when restoring ContentDocumentLinks may be something like:

Document with ID: {Salesforce ID} is already linked with the entity with ID: {Salesforce ID}

Remember, when GRAX inserts the ContentVersion, Salesforce autocreates a ContentDocument and will also naturally create a ContentDocumentLink to share the ContentDocument with the restoring user (which is the API user specified in the GRAX Settings). So if you subsequently try to restore a ContentDocumentLink for that user, you expectedly get an error saying it already exists, since Salesforce had auto-created it.