Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
sa28-00 [2016/12/12 17:31] – Justin Willey | sa28-00 [2021/11/26 12:45] (current) – Michael Scott | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Configuring External Blob (Document) Storage ====== | ====== Configuring External Blob (Document) Storage ====== | ||
- | ===Introduction=== | + | ====Introduction==== |
This is the mechanism for storing blobs outside the database. Blob (Binary Large OBject) is a generic term for documents (CVs, letters, photos, videos, spreadsheets etc) stored in the database. | This is the mechanism for storing blobs outside the database. Blob (Binary Large OBject) is a generic term for documents (CVs, letters, photos, videos, spreadsheets etc) stored in the database. | ||
Line 8: | Line 8: | ||
<note warning> | <note warning> | ||
- | ===Configuration=== | + | ====Configuration==== |
Steps to start using External Storage | Steps to start using External Storage | ||
- Create a folder on the database machine under which the blob files will be stored. Ensure the server process has full rights to it including the ability to create subfolders. | - Create a folder on the database machine under which the blob files will be stored. Ensure the server process has full rights to it including the ability to create subfolders. | ||
- The most important bit – ensure that the designated folder is backed up, preferably by some kind of live sync arrangement. | - The most important bit – ensure that the designated folder is backed up, preferably by some kind of live sync arrangement. | ||
- | - It is highly desirable that the designated folder is ONLY accessible by the Windows user account that the database engine is run under and the user account used for the sync / backup process. This will reduce the chance of any inadvertent editing / deleting of the blob files. | + | - It is highly desirable that the designated folder is ONLY accessible by the Windows user account that the database engine is run under and the user account used for the sync / backup process. This will reduce the chance of any inadvertent editing / deleting of the blob files, and can help provide protection against ransomware attacks. |
- | - Set params.BlobExternalRootFolder to the path to the above folder - for example:< | + | - Set params.BlobExternalRootFolder to the path to the above folder - for example:< |
- | - Create a trigger to delete | + | |
- | ORDER 1 ON " | + | |
- | REFERENCING OLD AS old_blob | + | |
- | FOR EACH ROW | + | |
- | WHEN (old_blob.externalfilepath is not null) | + | |
- | BEGIN | + | |
- | call xp_cmdshell(' | + | |
- | END</ | + | |
- Set params.BlobExternalStorage to 1 ie:< | - Set params.BlobExternalStorage to 1 ie:< | ||
- | From this point every blob that is created or edited will be saved externally. The BlobRelocate.xml job can be used to shift existing blobs out incrementally. | + | As users re-enter IQX, every blob that is created or edited will be saved externally. It is important therefore to get all users to exit and re login to IQX once the changes have been made. The [[sa28-00# |
<note warning> | <note warning> | ||
- | ===Accessing blobs in SQL=== | + | ====Accessing blobs in SQL==== |
To access blobs in reports or other queries, use the BlobStoreFetch() database function. This function will work for all blobs whether stored internally or externally. | To access blobs in reports or other queries, use the BlobStoreFetch() database function. This function will work for all blobs whether stored internally or externally. | ||
Line 36: | Line 28: | ||
For example: to retrieve candidate images use < | For example: to retrieve candidate images use < | ||
- | ===Moving Blobs Back Into The Database=== | + | ====Moving Blobs Back Into The Database==== |
- | To reverse the process, change the setting of BlobExternalStorage - new and edited blobs will now be stored internally. Again BlobRelocate will move the existing blobs for you. | + | To reverse the process, change the setting of BlobExternalStorage - new and edited blobs will now be stored internally. Again BlobRelocate.xml will move the existing blobs for you. |
- | + | ||
- | ===BlobRelocate Job=== | + | |
+ | ====BlobRelocate Job==== | ||
<sxh xml> | <sxh xml> | ||
<?xml version=" | <?xml version=" | ||
Line 79: | Line 70: | ||
</ | </ | ||
</ | </ | ||
+ | ==== Validating the External Storage ==== | ||
- | === Validating the External Storage === | + | Once the blobs are stored outside the database, the normal database validation cannot check that everything is present and correct. The stored procedure |
- | + | ||
- | Once the blobs are stored outside the database, the normal database validation cannot check that everything is present and correct. The stored procedure | + | |
- | + | ||
- | <sxh SQL> | + | |
- | CREATE PROCEDURE " | + | |
- | RESULT (" | + | |
- | BEGIN | + | |
- | DECLARE " | + | |
- | DECLARE " | + | |
- | -- create temp table to hold errors | + | |
- | DECLARE LOCAL TEMPORARY TABLE BlobStoreCheckIssue(" | + | |
- | -- regularise Standard and Alternative locations | + | |
- | SET " | + | |
- | IF " | + | |
- | -- @AlternativeLocation now holds the actual location of the files we want to check | + | |
- | IF right(" | + | |
- | IF right(" | + | |
- | -- loop through external blobs | + | |
- | FOR BlobLoop as BlobCursor NO SCROLL CURSOR | + | |
- | FOR select " | + | |
- | FOR READ ONLY | + | |
- | DO | + | |
- | if (select byte_substr(xp_read_file(BExtPath, | + | |
- | then insert into BlobStoreCheckIssue(" | + | |
- | END FOR; | + | |
- | -- recheck errors in case files were in use | + | |
- | FOR BlobLoop2 as BlobCursor2 NO SCROLL CURSOR | + | |
- | FOR select " | + | |
- | FOR READ ONLY | + | |
- | DO | + | |
- | if (select byte_substr(xp_read_file(BExtPath, | + | |
- | then update BlobStoreCheckIssue set " | + | |
- | else update BlobStoreCheckIssue set " | + | |
- | end if; | + | |
- | END FOR; | + | |
- | -- check existence of remaining issues | + | |
- | FOR BlobLoop3 as BlobCursor3 NO SCROLL CURSOR | + | |
- | FOR select " | + | |
- | FOR READ ONLY | + | |
- | DO | + | |
- | set " | + | |
- | set " | + | |
- | if exists (select * from sp_list_directory(" | + | |
- | then update BlobStoreCheckIssue set " | + | |
- | else update BlobStoreCheckIssue set " | + | |
- | end if; | + | |
- | END FOR; | + | |
- | select " | + | |
- | END; | + | |
- | </ | + | |
- | + | ||
- | The validation | + | |
< | < | ||
Line 139: | Line 79: | ||
|O|TI01FQSS161120130006|i: | |O|TI01FQSS161120130006|i: | ||
- | Orphaned Blobs in the file system can be identified with this stored procedure: | + | Orphaned Blobs in the file system can be identified with this stored procedure: |
<sxh SQL> | <sxh SQL> | ||
Line 147: | Line 87: | ||
BEGIN | BEGIN | ||
DECLARE @StandardLocation long varchar; | DECLARE @StandardLocation long varchar; | ||
- | DECLARE LOCAL TEMPORARY TABLE BlobFiles(" | + | DECLARE LOCAL TEMPORARY TABLE BlobFiles(" |
+ | | ||
-- regularise Standard and Alternative locations | -- regularise Standard and Alternative locations | ||
SET " | SET " | ||
Line 159: | Line 100: | ||
-- Find the files in the file system | -- Find the files in the file system | ||
INSERT INTO BlobFiles(" | INSERT INTO BlobFiles(" | ||
- | SELECT ' | + | SELECT ' |
+ | from sp_list_directory(@AlternativeLocation, | ||
CREATE INDEX A ON BlobFiles(" | CREATE INDEX A ON BlobFiles(" | ||
-- select those files only listed in the file system | -- select those files only listed in the file system | ||
SELECT FilePath , | SELECT FilePath , | ||
- | | + | |
+ | | ||
END; | END; | ||
</ | </ | ||
Line 172: | Line 115: | ||
which gives a result like: | which gives a result like: | ||
- | ^FilePath^FileSizeInKB^Created^Modified^Accessed^ | + | ^FilePath^ FileSizeInKB^ Created^ Modified^ Accessed^ |
|i: | |i: | ||
|i: | |i: | ||
Line 179: | Line 122: | ||
Each of these procedures can take an optional parameter of an alternative BlobStore folder, if specified, this will be compared with the contents of the BlobStore instead. This can be useful for checking that the backup of the external BlobStore is being correctly replicated. | Each of these procedures can take an optional parameter of an alternative BlobStore folder, if specified, this will be compared with the contents of the BlobStore instead. This can be useful for checking that the backup of the external BlobStore is being correctly replicated. | ||
| | ||
+ |