PageSourceSearch

https://www.ractoon.com/_next/static/chunks/pages/articles/adventu…bles-from-mysql-mariadb-a0a9b696f3cab560.js

js ractoon.com collected 2026-09-25 20:32:49 UTC 20,670 bytes, 1 lines download raw bytes

1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[232],{2910:function(e,n,a){(window.__NEXT_P=window.__NEXT_P||[]).push(["/articles/adventures-in-recovering-innodb-tables-from-mysql-mariadb",function(){return a(5324)}])},5324:function(e,n,a){"use strict";a.r(n),a.d(n,{default:function(){return l},meta:function(){return o}});var s=a(5893),t=a(1151),r=a(312);let o={author:"ractoon",date:"2024-08-01",title:"Adventures in Recovering InnoDB Tables from a MySQL/MariaDB Database",tags:["InnoDB","MySQL","MariaDB"],description:"Several methods you can use to recover data from InnoDB tables."},c=e=>(0,s.jsx)(r.B,{meta:o,...e});function i(e){let n={a:"a",blockquote:"blockquote",code:"code",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",span:"span",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"A crashed server, a broken database, and a client in need. Sounds like a recipe for an interesting day."}),"\n",(0,s.jsx)(n.h2,{children:"Plan A: Use a Tool"}),"\n",(0,s.jsx)(n.p,{children:"Searching revealed tools such as:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/twindb/undrop-for-innodb",children:"https://github.com/twindb/undrop-for-innodb"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://launchpad.net/percona-data-recovery-tool-for-innodb",children:"https://launchpad.net/percona-data-recovery-tool-for-innodb"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"That were several years old. I didn't have much luck using them, and felt like I was being nudged towards their commerical offerings for the up-to-date solution."}),"\n",(0,s.jsx)(n.p,{children:"I figured I could spin something up to copy things over, and just dump the data. How hard could it be? The 'ol developer's credo definitely kicked in here:"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"We do these things not because they are easy, but because we thought they were going to be easy."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{children:"Plan B: Spin up a Docker Container Using the Same Database Version"}),"\n",(0,s.jsx)(n.p,{children:"I was hoping to just copy down the database files, fire up a docker container using the same version of database that the server is using, and then dump the database. The first step was to locate the database files on the server."}),"\n",(0,s.jsxs)(n.p,{children:["In this case they lived at ",(0,s.jsx)(n.code,{children:"/var/lib/mysql"})," so I packaged up that whole directory and downloaded it."]}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsxs)(n.code,{className:"language-bash",children:[(0,s.jsx)(n.span,{className:"token function",children:"tar"})," -czf /var/lib/mysql database.tar.gz\n"]})}),"\n",(0,s.jsx)(n.p,{children:"After downloading unpack the directory wherever you'd like:"}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsxs)(n.code,{className:"language-bash",children:[(0,s.jsx)(n.span,{className:"token function",children:"tar"})," -xz database.tar.gz\n"]})}),"\n",(0,s.jsx)(n.p,{children:"Next is figuring out what version of MySQL was running on the server."}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsx)(n.code,{className:"language-bash",children:"mysql --version\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Which showed: ",(0,s.jsx)(n.code,{children:"mysql  Ver 15.1 Distrib 10.3.39-MariaDB, for debian-linux-gnu (x86_64)"})]}),"\n",(0,s.jsx)(n.p,{children:"So the server was actually running MariaDB 10.3.39."}),"\n",(0,s.jsx)(n.p,{children:"Alright, now we can get the docker 
1container up and running locally using that specific version:"}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsxs)(n.code,{className:"language-bash",children:[(0,s.jsx)(n.span,{className:"token function",children:"docker"})," run -p ",(0,s.jsx)(n.span,{className:"token number",children:"3306"}),":3306 ",(0,s.jsx)(n.span,{className:"token punctuation",children:"\\"}),"\n  --name dbrescue ",(0,s.jsx)(n.span,{className:"token punctuation",children:"\\"}),"\n  -v /path/to/local/downloaded/database:/var/lib/mysql:Z ",(0,s.jsx)(n.span,{className:"token punctuation",children:"\\"}),"\n  -d mariadb:10.3.39\n"]})}),"\n",(0,s.jsxs)(n.p,{children:["You can confirm the container is running as expected using ",(0,s.jsx)(n.code,{children:"docker ps"})," and you should see your container ",(0,s.jsx)(n.code,{children:"dbrescue"})," running."]}),"\n",(0,s.jsxs)(n.p,{children:["If you don't see it, check the logs for any errors using ",(0,s.jsx)(n.code,{children:"docker logs -f dbrescue"})]}),"\n",(0,s.jsx)(n.p,{children:"Now you should be able to hop into your container, and access the database. You'll need the the database username/password used on the server that the database came from."}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsxs)(n.code,{className:"language-bash",children:[(0,s.jsx)(n.span,{className:"token function",children:"docker"})," ",(0,s.jsx)(n.span,{className:"token builtin class-name",children:"exec"})," -it dbrescue ",(0,s.jsx)(n.span,{className:"token function",children:"bash"}),"\n"]})}),"\n",(0,s.jsx)(n.p,{children:"Then in the container open up a database terminal:"}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsx)(n.code,{className:"language-bash",children:"mysql -u your_username -p\n"})}),"\n",(0,s.jsx)(n.p,{children:"Enter the password when prompted and you should be in the database terminal. Make sure you can see your database, and tables, that you need to recover:"}),"\n",(0,s.jsx)(n.pre,{className:"language-sql",children:(0,s.jsxs)(n.code,{className:"language-sql",children:[(0,s.jsx)(n.span,{className:"token keyword",children:"SHOW"})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"DATABASES"}),(0,s.jsx)(n.span,{className:"token punctuation",children:";"}),"\n",(0,s.jsx)(n.span,{className:"token keyword",children:"USE"})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"DATABASE"})," your_database",(0,s.jsx)(n.span,{className:"token punctuation",children:";"}),"\n",(0,s.jsx)(n.span,{className:"token keyword",children:"SHOW"})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"TABLES"}),(0,s.jsx)(n.span,{className:"token punctuation",children:";"}),"\n"]})}),"\n",(0,s.jsx)(n.p,{children:"If things are looking good you can attempt to dump the database."}),"\n",(0,s.jsx)(n.pre,{className:"language-sql",children:(0,s.jsxs)(n.code,{className:"language-sql",children:["mysqldump ",(0,s.jsx)(n.span,{className:"token operator",children:"-"}),"u your_username ",(0,s.jsx)(n.span,{className:"token operator",children:"-"}),"p your_database ",(0,s.jsx)(n.span,{className:"token operator",children:">"})," database_dump",(0,s.jsx)(n.span,{className:"token punctuation",children:"."}),(0,s.jsx)(n.span,{className:"token keyword",children:"sql"}),"\n"]})}),"\n",(0,s.jsx)(n.p,{children:"If that process completes you can switch back to your local terminal (keep the docker container running) and copy the dump:"}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsxs)(n.code,{className:"language-bash",children:[(0,s.jsx)(n.span,{className:"token function",children:"docker"})," ",(0,s.jsx)(n.span,{className:"token function",children:"cp"})," dbrescue:/file/path/to/database_dump.sql /local/path/destination/\n"]})}),"\n",(0,s.jsx)(n.p,{children:"Hopefully that worked and you've now got your database back up and running. Unfortunately, I was seeing errors when trying to dump the database."}),"\n",(0,s.jsx)(n.h2,{children:"Plan C: Re-Create the Tables and Copy the Data"}),"\n",(0,s.jsxs)(n.p,{children:["If Plan B fails you can also manually re-create the database and tables on your new server, then copy over the ",(0,s.jsx)(n.code,{children:".ibd"})," files that contain each tables data."]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Create a new database"}),"\n",(0,s.jsx)(n.li,{children:"Create the tables from the old database, using the same name and structure"}),"\n",(0,s.jsxs)(n.li,{children:["Copy over the ",(0,s.jsx)(n.code,{children:".ibd"})," files from the old server to your new one, overwriting the ones that were automatically created when you created the tables"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["You may be noticing that your old 
1server has ",(0,s.jsx)(n.code,{children:".frm"})," and ",(0,s.jsx)(n.code,{children:".ibd"})," files for each database, but you're only overwriting the ",(0,s.jsx)(n.code,{children:".ibd"})," files. Since both files are automatically created when you create the table in your new database the only missing piece would be the data from the ",(0,s.jsx)(n.code,{children:".ibd"})," files."]}),"\n",(0,s.jsxs)(n.p,{children:["However, if you can't access the old server database to check what the old table structure was the ",(0,s.jsx)(n.code,{children:".frm"})," files contain the table schema."]}),"\n",(0,s.jsxs)(n.p,{children:["You can use a script like ",(0,s.jsx)(n.a,{href:"https://dbsake.readthedocs.io",children:"dbsake"})," to generate the ",(0,s.jsx)(n.code,{children:"CREATE TABLE"})," statement necessary to re-create the table. Once downloaded you can use the ",(0,s.jsx)(n.code,{children:"frmdump"})," command on each file to display the SQL:"]}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsx)(n.code,{className:"language-bash",children:"dbsake frmdump /path/to/foo.frm\n"})}),"\n",(0,s.jsx)(n.p,{children:"Which will output something like:"}),"\n",(0,s.jsx)(n.pre,{className:"language-sql",children:(0,s.jsxs)(n.code,{className:"language-sql",children:[(0,s.jsx)(n.span,{className:"token keyword",children:"CREATE"})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"TABLE"})," ",(0,s.jsxs)(n.span,{className:"token identifier",children:[(0,s.jsx)(n.span,{className:"token punctuation",children:"`"}),"foo",(0,s.jsx)(n.span,{className:"token punctuation",children:"`"})]})," ",(0,s.jsx)(n.span,{className:"token punctuation",children:"("}),"\n  ",(0,s.jsxs)(n.span,{className:"token identifier",children:[(0,s.jsx)(n.span,{className:"token punctuation",children:"`"}),"name",(0,s.jsx)(n.span,{className:"token punctuation",children:"`"})]})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"varchar"}),(0,s.jsx)(n.span,{className:"token punctuation",children:"("}),(0,s.jsx)(n.span,{className:"token number",children:"64"}),(0,s.jsx)(n.span,{className:"token punctuation",children:")"})," ",(0,s.jsx)(n.span,{className:"token operator",children:"NOT"})," ",(0,s.jsx)(n.span,{className:"token boolean",children:"NULL"})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"DEFAULT"})," ",(0,s.jsx)(n.span,{className:"token string",children:"''"}),(0,s.jsx)(n.span,{className:"token punctuation",children:","}),"\n  ",(0,s.jsxs)(n.span,{className:"token identifier",children:[(0,s.jsx)(n.span,{className:"token punctuation",children:"`"}),"dl",(0,s.jsx)(n.span,{className:"token punctuation",children:"`"})]})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"varchar"}),(0,s.jsx)(n.span,{className:"token punctuation",children:"("}),(0,s.jsx)(n.span,{className:"token number",children:"128"}),(0,s.jsx)(n.span,{className:"token punctuation",children:")"})," ",(0,s.jsx)(n.span,{className:"token operator",children:"NOT"})," ",(0,s.jsx)(n.span,{className:"token boolean",children:"NULL"})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"DEFAULT"})," ",(0,s.jsx)(n.span,{className:"token string",children:"''"}),(0,s.jsx)(n.span,{className:"token punctuation",children:","}),"\n  ",(0,s.jsx)(n.span,{className:"token keyword",children:"PRIMARY"})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"KEY"})," ",(0,s.jsx)(n.span,{className:"token punctuation",children:"("}),(0,s.jsxs)(n.span,{className:"token identifier",children:[(0,s.jsx)(n.span,{className:"token punctuation",children:"`"}),"name",(0,s.jsx)(n.span,{className:"token punctuation",children:"`"})]}),(0,s.jsx)(n.span,{className:"token punctuation",children:")"}),"\n",(0,s.jsx)(n.span,{className:"token punctuation",children:")"})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"ENGINE"}),(0,s.jsx)(n.span,{className:"token operator",children:"="}),"MyISAM ",(0,s.jsx)(n.span,{className:"token keyword",children:"DEFAULT"})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"CHARSET"}),(0,s.jsx)(n.span,{className:"token operator",children:"="}),"utf8",(0,s.jsx)(n.span,{className:"token punctuation",children:";"}),"\n"]})}),"\n",(0,s.jsxs)(n.p,{children:["Note: ",(0,s.jsx)(n.code,{children:"dbsake"})," is built on Python 2, so I had to set up ",(0,s.jsx)(n.a,{href:"https://github.com/pyenv/pyenv",children:"pyenv"})," to switch my system from version 3 to version 2 to run it."]}),"\n",(0,s.jsx)(n.h2,{children:"Plan D: Errors"}),"\n",(0,s.jsxs)(n.p,{children:["Again, hopefully that did the trick and you're able to access your data once again. At this point I was seeing errors when trying to start up the database, and seemed like I needed to ",(0,s.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.4/en/forcing-innodb-recovery.html",children:"force InnoDB recovery"}),"."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Before modifying this make sure to have a backup though, as it can affect your data."})}),"\n",(0,s.jsx)(n.p,{children:"You can force recovery by adding this line to your option file:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"innodb_force_recovery = 1\n"})}),"\n",(0,s.jsxs)(n.p,{children:["By default this value is ",(0,s.jsx)(n.code,{children:"0"})," (normal startup without forced recovery). It goes up to ",(0,s.jsx)(n.code,{children:"6"}),", and anything above ",(0,s.jsx)(n.code,{children:"4"})," is considered risky as data files can be permanently corrupted (again, make backups before proceeding)."]}),"\n",(0,s.jsxs)(n.p,{children:["I ended up needing to crank my ",(0,s.jsx)(n.code,{children:"innodb_force_recovery"})," to ",(0,s.jsx)(n.code,{children:"6"}),", do a ",(0,s.jsx)(n.code,{children:"mysqldump"}),", and then copy everything over to an entirely new database to restore things."]}),"\n",(0,s.jsx)(n.p,{children:"Fingers crossed that one of these restored the data you needed, and let you rescue it."})]})}function l(e={}){return(0,s.jsx)(c,{...e,children:(0,s.jsx)(i,{...e})})}},312:function(e,n,a){"use strict";a.d(n,{B:function(){return x}});var s=a(5893),t=a(9008),r=a.n(t),o=a(1664),c=a.n(o),i=a(1163),l=a(3223),d=a(6434),h=a(512);function u({children:e,className:n}){return(0,s.jsx)("div",{className:(0,h.Z)(n,"prose dark:prose-invert"),children:e})}var p=a(7330);function m(e){return(0,s.jsx)("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",...e,children:(0,s.jsx)("path",{d:"M7.25 11.25 3.75 8m0 0 3.5-3.25M3.75 8h8.5",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({children:e,meta:n,isRssFeed:a=!1,previousPathname:t}){if(a)return e;let o=(0,i.useRouter)();return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(r(),{children:[(0,s.jsx)("title",{children:`${n.title} | ractoon`}),(0,s.jsx)("meta",{name:"description",content:n.description})]}),(0,s.jsx)(l.W,{className:"mt-16 lg:mt-32",children:(0,s.jsx)("div",{className:"xl:relative",children:(0,s.jsxs)("div",{className:"mx-auto max-w-2xl",children:[t&&(0,s.jsx)("button",{type:"button",onClick:()=>o.back(),"aria-label":"Go back to articles",className:"group mb-8 flex h-10 w-10 items-center justify-center rounded-full bg-white shadow-md shadow-zinc-800/5 ring-1 ring-zinc-900/5 transition dark:border dark:border-zinc-700/50 dark:bg-zinc-800 dark:ring-0 dark:ring-white/10 dark:hover:border-zinc-700 dark:hover:ring-white/20 lg:absolute lg:-left-5 lg:mb-0 lg:-mt-2 xl:-top-1.5 xl:left-0 xl:mt-0",children:(0,s.jsx)(m,{className:"h-4 w-4 stroke-zinc-500 transition group-hover:stroke-zinc-700 dark:stroke-zinc-500 dark:group-hover:stroke-zinc-400"})}),(0,s.jsxs)("article",{children:[(0,s.jsxs)("header",{className:"flex flex-col",children:[(0,s.jsx)("h1",{className:"bg-gradient-to-br from-ractoon-blue-light to-ractoon-blue-dark text-transparent bg-clip-text mt-6 text-4xl font-bold tracking-tight sm:leading-[4rem] sm:text-5xl",children:n.title}),(0,s.jsxs)("time",{dateTime:n.date,className:"order-first flex items-center text-base text-zinc-400 dark:text-zinc-500",children:[(0,s.jsx)("span",{className:"h-4 w-0.5 rounded-full bg-zinc-200 dark:bg-zinc-500"}),(0,s.jsx)("span",{className:"ml-3",children:(0,p.p)(n.date)})]})]}),(0,s.jsx)(u,{className:"mt-8",children:e})]}),(0,s.jsx)("aside",{children:(0,s.jsx)(d.m,{className:"mt-24"})}),(0,s.jsx)("footer",{children:(0,s.jsx)(u,{children:(0,s.jsxs)("p",{className:"text-center",children:["Questions or comments? Hit me up on Twitter ",(0,s.jsx)(c(),{href:"https://twitter.com/ractoon",target:"_blank",children:"@ractoon"})]})})})]})})})]})}},5534:function(e,n,a){"use strict";a.d(n,{z:function(){return i}});var s=a(5893),t=a(1664),r=a.n(t),o=a(512);let c={primary:"bg-zinc-600 font-semibold text-zinc-100 hover:bg-zinc-700 active:bg-zinc-800 active:text-zinc-100/70 dark:bg-zinc-700 dark:hover:bg-zinc-600 dark:active:bg-zinc-700 dark:active:text-zinc-100/70",secondary:"bg-zinc-50 font-medium text-zinc-900 hover:bg-zinc-100 active:bg-zinc-100 active:text-zinc-900/60 dark:bg-zinc-800/50 dark:text-zinc-300 dark:hover:bg-zinc-800 dark:hover:text-zinc-50 dark:active:bg-zinc-800/50 dark:active:text-zinc-50/70",brand:"border border-ractoon-blue-dark/50 font-semibold text-ractoon-blue-dark dark:text-ractoon-blue hover:border-ractoon-blue hover:text-ractoon-blue active:border-ractoon-blue/60 dark:border-ractoon-blue/50 dark:hover:border-ractoon-blue-light dark:hover:text-ractoon-blue-light dark:active:border-ractoon-blue-light/70"};function i({variant:e="primary",className:n,href:a,...t}){return n=(0,o.Z)("inline-flex items-center gap-2 justify-center rounded-md py-2 px-3 text-sm outline-offset-2 transition active:transition-none",c[e],n),a?(0,s.jsx)(r(),{href:a,className:n,...t}):(0,s.jsx)("button",{className:n,...t})}},6434:function(e,n,a){"use strict";a.d(n,{m:function(){return c}});var s=a(5893),t=a(512),r=a(5534);function o(e){return(0,s.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:"1.5",stroke:"currentColor",...e,children:(0,s.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75",className:"fill-zinc-100 stroke-zinc-400 dark:fill-zinc-100/10 dark:stroke-zinc-500"})})}function c({className:e}){return e=(0,t.Z)("bg-white/90 backdrop-blur-sm rounded-2xl border border-zinc-100 p-6 dark:bg-zinc-900/90 dark:border-zinc-700/40",e),(0,s.jsxs)("form",{action:"https://app.convertkit.com/forms/3928602/subscriptions",method:"post",target:"_blank",className:e,children:[(0,s.jsxs)("h2",{className:"flex text-sm font-semibold text-zinc-900 dark:text-zinc-100",children:[(0,s.jsx)(o,{className:"h-6 w-6 flex-none"}),(0,s.jsx)("span",{className:"ml-2",children:"Stay up to date"})]}),(0,s.jsx)("p",{className:"mt-2 text-sm text-zinc-600 dark:text-zinc-400",children:"Get notified when I publish something new, and unsubscribe at any time."}),(0,s.jsxs)("div",{className:"mt-6 flex",children:[(0,s.jsx)("input",{type:"email",placeholder:"Email address","aria-label":"Email address",name:"email_address",required:!0,className:"min-w-0 flex-auto appearance-none rounded-md border border-zinc-900/10 bg-white px-3 py-[calc(theme(sp
1acing.2)-1px)] shadow-md shadow-zinc-800/5 placeholder:text-zinc-400 focus:border-ractoon-blue focus:outline-none focus:ring-4 focus:ring-ractoon-blue/10 dark:border-zinc-700 dark:bg-zinc-700/[0.15] dark:text-zinc-200 dark:placeholder:text-zinc-500 dark:focus:border-ractoon-blue-light dark:focus:ring-ractoon-blue-light/10 sm:text-sm"}),(0,s.jsx)(r.z,{type:"submit",className:"ml-4 flex-none",children:"Join"})]})]})}},7330:function(e,n,a){"use strict";function s(e){return new Date(`${e}T00:00:00Z`).toLocaleDateString("en-US",{day:"numeric",month:"long",year:"numeric",timeZone:"UTC"})}a.d(n,{p:function(){return s}})},9008:function(e,n,a){e.exports=a(7828)},1151:function(e,n,a){"use strict";a.d(n,{a:function(){return r}});var s=a(7294);let t=s.createContext({});function r(e){let n=s.useContext(t);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}}},function(e){e.O(0,[888,774,179],function(){return e(e.s=2910)}),_N_E=e.O()}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.