11.1Syamt-- $NetBSD: check.sql,v 1.1 2011/10/12 01:05:00 yamt Exp $ 21.1Syamt 31.1Syamt-- Copyright (c)2010,2011 YAMAMOTO Takashi, 41.1Syamt-- All rights reserved. 51.1Syamt-- 61.1Syamt-- Redistribution and use in source and binary forms, with or without 71.1Syamt-- modification, are permitted provided that the following conditions 81.1Syamt-- are met: 91.1Syamt-- 1. Redistributions of source code must retain the above copyright 101.1Syamt-- notice, this list of conditions and the following disclaimer. 111.1Syamt-- 2. Redistributions in binary form must reproduce the above copyright 121.1Syamt-- notice, this list of conditions and the following disclaimer in the 131.1Syamt-- documentation and/or other materials provided with the distribution. 141.1Syamt-- 151.1Syamt-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 161.1Syamt-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 171.1Syamt-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 181.1Syamt-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 191.1Syamt-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 201.1Syamt-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 211.1Syamt-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 221.1Syamt-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 231.1Syamt-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 241.1Syamt-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 251.1Syamt-- SUCH DAMAGE. 261.1Syamt 271.1Syamt-- filesystem consistency checks. ie. something like "fsck -n" 281.1Syamt 291.1SyamtBEGIN; 301.1SyamtSET TRANSACTION ISOLATION LEVEL REPEATABLE READ; 311.1SyamtSET TRANSACTION READ ONLY; 321.1SyamtSET search_path TO pgfs; 331.1SyamtSELECT count(*) AS "unreferenced files (dirent)" 341.1Syamt FROM file f LEFT JOIN dirent d 351.1Syamt ON f.fileid = d.child_fileid 361.1Syamt WHERE f.fileid <> 1 AND d.child_fileid IS NULL; 371.1SyamtSELECT count(*) AS "unreferenced files (nlink)" 381.1Syamt FROM file f 391.1Syamt WHERE f.nlink = 0; 401.1SyamtSELECT count(*) AS "regular files without datafork" 411.1Syamt FROM file f LEFT JOIN datafork df 421.1Syamt ON f.fileid = df.fileid 431.1Syamt WHERE df.fileid IS NULL AND f.type IN ('regular', 'link'); 441.1SyamtSELECT count(*) AS "broken datafork reference" 451.1Syamt FROM file f INNER JOIN datafork df 461.1Syamt ON f.fileid = df.fileid 471.1Syamt WHERE f.type NOT IN ('regular', 'link'); 481.1SyamtSELECT count(*) AS "unreferenced dataforks" 491.1Syamt FROM file f RIGHT JOIN datafork df 501.1Syamt ON f.fileid = df.fileid 511.1Syamt WHERE f.fileid IS NULL; 521.1SyamtSELECT count(*) AS "dataforks without large object" 531.1Syamt FROM datafork df LEFT JOIN pg_largeobject_metadata lm 541.1Syamt ON df.loid = lm.oid 551.1Syamt WHERE lm.oid IS NULL; 561.1SyamtSELECT count(*) AS "unreferenced large objects" 571.1Syamt FROM datafork df RIGHT JOIN pg_largeobject_metadata lm 581.1Syamt ON df.loid = lm.oid 591.1Syamt WHERE df.loid IS NULL; 601.1SyamtSELECT count(*) AS "dirent broken parent_fileid references" 611.1Syamt FROM dirent d LEFT JOIN file f 621.1Syamt ON d.parent_fileid = f.fileid 631.1Syamt WHERE f.fileid IS NULL OR f.type <> 'directory'; 641.1SyamtSELECT count(*) AS "dirent broken child_fileid references" 651.1Syamt FROM dirent d LEFT JOIN file f 661.1Syamt ON d.child_fileid = f.fileid 671.1Syamt WHERE f.fileid IS NULL; 681.1SyamtSELECT count(*) AS "dirent loops" FROM file f WHERE EXISTS ( 691.1Syamt WITH RECURSIVE r AS 701.1Syamt ( 711.1Syamt SELECT d.* FROM dirent d 721.1Syamt WHERE d.child_fileid = f.fileid 731.1Syamt UNION ALL 741.1Syamt SELECT d.* FROM dirent d INNER JOIN r 751.1Syamt ON d.child_fileid = r.parent_fileid 761.1Syamt ) 771.1Syamt SELECT * FROM r WHERE r.parent_fileid = f.fileid); 781.1SyamtSELECT count(*) AS "broken nlink" 791.1Syamt FROM 801.1Syamt ( 811.1Syamt SELECT coalesce(fp.fileid, fc.fileid) AS fileid, 821.1Syamt coalesce(fp.nlink, 0) + coalesce(fc.nlink, 0) + 831.1Syamt CASE 841.1Syamt WHEN coalesce(fp.fileid, fc.fileid) = 1 THEN 1 851.1Syamt ELSE 0 861.1Syamt END 871.1Syamt AS nlink 881.1Syamt FROM 891.1Syamt ( 901.1Syamt SELECT child_fileid AS fileid, count(*) AS nlink 911.1Syamt FROM dirent 921.1Syamt GROUP BY child_fileid 931.1Syamt ) fp 941.1Syamt FULL JOIN 951.1Syamt ( 961.1Syamt SELECT count(*) AS nlink, d.parent_fileid AS fileid 971.1Syamt FROM dirent d 981.1Syamt JOIN file f 991.1Syamt ON d.child_fileid = f.fileid 1001.1Syamt WHERE f.type = 'directory' 1011.1Syamt GROUP BY parent_fileid 1021.1Syamt ) fc 1031.1Syamt ON fp.fileid = fc.fileid 1041.1Syamt ) d 1051.1Syamt FULL JOIN file f 1061.1Syamt ON d.fileid = f.fileid 1071.1Syamt WHERE (d.nlink IS NULL AND (f.fileid <> 1 AND f.nlink <> 0)) 1081.1Syamt OR f.nlink IS NULL 1091.1Syamt OR d.nlink <> f.nlink; 1101.1SyamtCOMMIT; 111