1-- $NetBSD: check.sql,v 1.1 2011/10/12 01:05:00 yamt Exp $ 2 3-- Copyright (c)2010,2011 YAMAMOTO Takashi, 4-- All rights reserved. 5-- 6-- Redistribution and use in source and binary forms, with or without 7-- modification, are permitted provided that the following conditions 8-- are met: 9-- 1. Redistributions of source code must retain the above copyright 10-- notice, this list of conditions and the following disclaimer. 11-- 2. Redistributions in binary form must reproduce the above copyright 12-- notice, this list of conditions and the following disclaimer in the 13-- documentation and/or other materials provided with the distribution. 14-- 15-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25-- SUCH DAMAGE. 26 27-- filesystem consistency checks. ie. something like "fsck -n" 28 29BEGIN; 30SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; 31SET TRANSACTION READ ONLY; 32SET search_path TO pgfs; 33SELECT count(*) AS "unreferenced files (dirent)" 34 FROM file f LEFT JOIN dirent d 35 ON f.fileid = d.child_fileid 36 WHERE f.fileid <> 1 AND d.child_fileid IS NULL; 37SELECT count(*) AS "unreferenced files (nlink)" 38 FROM file f 39 WHERE f.nlink = 0; 40SELECT count(*) AS "regular files without datafork" 41 FROM file f LEFT JOIN datafork df 42 ON f.fileid = df.fileid 43 WHERE df.fileid IS NULL AND f.type IN ('regular', 'link'); 44SELECT count(*) AS "broken datafork reference" 45 FROM file f INNER JOIN datafork df 46 ON f.fileid = df.fileid 47 WHERE f.type NOT IN ('regular', 'link'); 48SELECT count(*) AS "unreferenced dataforks" 49 FROM file f RIGHT JOIN datafork df 50 ON f.fileid = df.fileid 51 WHERE f.fileid IS NULL; 52SELECT count(*) AS "dataforks without large object" 53 FROM datafork df LEFT JOIN pg_largeobject_metadata lm 54 ON df.loid = lm.oid 55 WHERE lm.oid IS NULL; 56SELECT count(*) AS "unreferenced large objects" 57 FROM datafork df RIGHT JOIN pg_largeobject_metadata lm 58 ON df.loid = lm.oid 59 WHERE df.loid IS NULL; 60SELECT count(*) AS "dirent broken parent_fileid references" 61 FROM dirent d LEFT JOIN file f 62 ON d.parent_fileid = f.fileid 63 WHERE f.fileid IS NULL OR f.type <> 'directory'; 64SELECT count(*) AS "dirent broken child_fileid references" 65 FROM dirent d LEFT JOIN file f 66 ON d.child_fileid = f.fileid 67 WHERE f.fileid IS NULL; 68SELECT count(*) AS "dirent loops" FROM file f WHERE EXISTS ( 69 WITH RECURSIVE r AS 70 ( 71 SELECT d.* FROM dirent d 72 WHERE d.child_fileid = f.fileid 73 UNION ALL 74 SELECT d.* FROM dirent d INNER JOIN r 75 ON d.child_fileid = r.parent_fileid 76 ) 77 SELECT * FROM r WHERE r.parent_fileid = f.fileid); 78SELECT count(*) AS "broken nlink" 79 FROM 80 ( 81 SELECT coalesce(fp.fileid, fc.fileid) AS fileid, 82 coalesce(fp.nlink, 0) + coalesce(fc.nlink, 0) + 83 CASE 84 WHEN coalesce(fp.fileid, fc.fileid) = 1 THEN 1 85 ELSE 0 86 END 87 AS nlink 88 FROM 89 ( 90 SELECT child_fileid AS fileid, count(*) AS nlink 91 FROM dirent 92 GROUP BY child_fileid 93 ) fp 94 FULL JOIN 95 ( 96 SELECT count(*) AS nlink, d.parent_fileid AS fileid 97 FROM dirent d 98 JOIN file f 99 ON d.child_fileid = f.fileid 100 WHERE f.type = 'directory' 101 GROUP BY parent_fileid 102 ) fc 103 ON fp.fileid = fc.fileid 104 ) d 105 FULL JOIN file f 106 ON d.fileid = f.fileid 107 WHERE (d.nlink IS NULL AND (f.fileid <> 1 AND f.nlink <> 0)) 108 OR f.nlink IS NULL 109 OR d.nlink <> f.nlink; 110COMMIT; 111