Files
pages/2020/06/17/backup.html
2025-12-31 16:00:29 +00:00

422 lines
33 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Begin Jekyll SEO tag v2.8.0 -->
<title>论备份的重要性 | Mayx的博客</title>
<meta name="generator" content="Jekyll v3.9.5" />
<meta property="og:title" content="论备份的重要性" />
<meta name="author" content="mayx" />
<meta property="og:locale" content="zh_CN" />
<meta name="description" content="只有事情发生到自己头上才想到要解决" />
<meta property="og:description" content="只有事情发生到自己头上才想到要解决" />
<meta property="og:site_name" content="Mayx的博客" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2020-06-17T00:00:00+08:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="论备份的重要性" />
<meta name="google-site-verification" content="huTYdEesm8NaFymixMNqflyCp6Jfvd615j5Wq1i2PHc" />
<meta name="msvalidate.01" content="0ADFCE64B3557DC4DC5F2DC224C5FDDD" />
<meta name="yandex-verification" content="fc0e535abed800be" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"mayx"},"dateModified":"2020-06-17T00:00:00+08:00","datePublished":"2020-06-17T00:00:00+08:00","description":"只有事情发生到自己头上才想到要解决","headline":"论备份的重要性","mainEntityOfPage":{"@type":"WebPage","@id":"/2020/06/17/backup.html"},"publisher":{"@type":"Organization","logo":{"@type":"ImageObject","url":"https://avatars0.githubusercontent.com/u/17966333"},"name":"mayx"},"url":"/2020/06/17/backup.html"}</script>
<!-- End Jekyll SEO tag -->
<link rel="canonical" href="https://mabbs.github.io/2020/06/17/backup.html" />
<link type="application/atom+xml" rel="alternate" href="/atom.xml" title="Mayx的博客" />
<link rel="alternate" type="application/rss+xml" title="Mayx的博客(RSS)" href="/rss.xml" />
<link rel="alternate" type="application/json" title="Mayx的博客(JSON Feed)" href="/feed.json" />
<link rel="stylesheet" href="/assets/css/style.css?v=1767196818" />
<!--[if !IE]> -->
<link rel="stylesheet" href="/Live2dHistoire/live2d/css/live2d.css" />
<!-- <![endif]-->
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Mayx的博客" />
<link rel="webmention" href="https://webmention.io/mabbs.github.io/webmention" />
<link rel="pingback" href="https://webmention.io/mabbs.github.io/xmlrpc" />
<link rel="preconnect" href="https://summary.mayx.eu.org" crossorigin="anonymous" />
<link rel="prefetch" href="https://www.blogsclub.org/badge/mabbs.github.io" as="image" />
<link rel="blogroll" type="text/xml" href="/blogroll.opml" />
<link rel="me" href="https://github.com/Mabbs" />
<script src="/assets/js/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.3/jquery.xdomainrequest.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<script>
var lastUpdated = new Date("Thu, 01 Jan 2026 00:00:18 +0800");
var BlogAPI = "https://summary.mayx.eu.org";
</script>
<script src="/assets/js/main.js"></script>
<!--[if !IE]> -->
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-137710294-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-137710294-1');
</script>
<script src="/assets/js/instant.page.js" type="module"></script>
<!-- <![endif]-->
</head>
<body>
<!--[if !IE]> --><noscript><marquee style="top: -15px; position: relative;"><small>发现当前浏览器没有启用JavaScript这不影响你的浏览但可能会有一些功能无法使用……</small></marquee></noscript><!-- <![endif]-->
<!--[if IE]><marquee style="top: -15px; position: relative;"><small>发现当前浏览器为Internet Explorer这不影响你的浏览但可能会有一些功能无法使用……</small></marquee><![endif]-->
<div class="wrapper">
<header class="h-card">
<h1><a class="u-url u-uid p-name" rel="me" href="/">Mayx的博客</a></h1>
<img src="https://avatars0.githubusercontent.com/u/17966333" fetchpriority="high" class="u-photo" alt="Logo" style="width: 90%; max-width: 300px; max-height: 300px;" />
<p class="p-note">Mayx's Home Page</p>
<form action="/search.html">
<input type="text" name="keyword" id="search-input-all" placeholder="Search blog posts.." />&#160;<input type="submit" value="搜索" />
</form>
<br />
<p class="view"><a class="u-url" href="/Mabbs/">About me</a></p>
<ul class="downloads">
<li style="width: 270px; border-right: none;"><a href="/MayxBlog.tgz">Download <strong>TGZ File</strong></a></li>
</ul>
</header>
<section class="h-entry">
<small><time class="date dt-published" datetime="2020-06-17T00:00:00+08:00">17 June 2020</time> - 字数统计3822 - 阅读大约需要14分钟 - Hits: <span id="/2020/06/17/backup.html" class="visitors">Loading...</span></small>
<h1 class="p-name">论备份的重要性</h1>
<p class="view">by <a class="p-author h-card" href="//github.com/Mabbs">mayx</a></p>
<div id="outdate" style="display:none;">
<hr /><p>
这是一篇创建于 <span id="outime"></span> 天前的文章,其中的信息可能已经有所发展或是发生改变。
</p>
</div>
<script>
daysold = Math.floor((new Date().getTime() - new Date("Wed, 17 Jun 2020 00:00:00 +0800").getTime()) / (24 * 60 * 60 * 1000));
if (daysold > 90) {
document.getElementById("outdate").style.display = "block";
document.getElementById("outime").innerHTML = daysold;
}
</script>
<hr />
<b>AI摘要</b>
<p id="ai-output">这篇文章讲述了作者在云服务器Vultr上遭遇数据丢失的经历由于服务器突然挂掉且回滚到的快照时间较早导致十几天的数据可能丢失。作者在服务器故障后发现Vultr未能有效恢复数据恢复仅能依靠旧的快照这让他反思了备份的重要性和供应商责任。他计划设置自动快照脚本以防止未来类似问题并考虑将数据备份到本地以增加安全度。作者认为个人不能完全依赖云服务商备份是保障数据安全的关键。</p>
<hr />
<ul><li><a href="#起因">起因</a></li><li><a href="#难以想象的垃圾服务商vultr">难以想象的垃圾服务商Vultr</a></li><li><a href="#亡羊补牢">亡羊补牢</a><ul><li><a href="#自动快照的脚本">自动快照的脚本</a></li></ul></li><li><a href="#后记">后记</a></li></ul>
<hr />
<main class="post-content e-content" role="main"><p>只有事情发生到自己头上才想到要解决<!--more--></p>
<h1 id="起因">
<a href="#起因"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 起因
</h1>
<p>今天早上发生了一件很糟糕的事情,一打开聊天软件就发现有人在说我维护的花火学园挂掉了,错误信息是无法访问源站。我觉得挺奇怪,服务器又没啥负载,我也有一段时间没登进去了,怎么服务器就挂掉了? </p><p>
我试着用SSH连接同样无法连接我发现事情不太对劲然后就登到了Vultr里看了看。结果发现我的服务器在00:00之后就像一个死人一样CPU负载被拉成了一条直线就那样保持0%的位置。我以为是因为莫名其妙的原因服务器关机了,然而我重启以后仍然没有解决问题。 </p><p>
登录到终端一看,<code class="language-plaintext highlighter-rouge">No bootable device</code>就这样显示在屏幕上硬盘直接读不出来了这下可不得了了我赶紧去快照里看了一下发现最后一次快照的时间在5月30日也就是说如果没能恢复数据这十几天的所有信息都将消失</p>
<h1 id="难以想象的垃圾服务商vultr">
<a href="#难以想象的垃圾服务商vultr"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 难以想象的垃圾服务商Vultr
</h1>
<p>首先我要做的事情当然是想办法先恢复服务,虽然那个快照有点早,但是先顶上再说吧…… </p><p>
想一想我的防护应该做的也没啥问题而且一般成功入侵服务器的人也应该是删库然后留一条信息的那种直接干死硬盘的我还真没见过。于是我开始发Ticket给Vultr看看到底是怎么回事。 </p><p>
Vultr在我问完的4个小时后给出了最终的解决方案把我的服务器直接重置在上面安了新的操作系统然后给我赔了两个月的服务器费用……原文如下</p>
<blockquote>
<p>Hello,</p>
<p>In the past 24 hours, we sent notification of a node failure impacting your cloud server listed above.</p>
<p>Despite extensive efforts, our attempts to manually recover your cloud server were unsuccessful.</p>
<p>Our engineering team is currently deploying new instances with the same operating system and IP and you will receive login details in a separate message. You may also deploy a backup or snapshot on a new instance with a new IP if you prefer.</p>
<p>Our staff will be applying a two month account credit for the affected services shortly.</p>
<p>Regards, </p><p>
Bryan M. </p><p>
Systems Administrator</p>
</blockquote>
<p>这真是太糟糕了作为一家云服务器商就直接把客户的数据搞没了然后就赔2个月的费用要知道数据无价啊就这么不负责任的吗简直是不可思议啊 </p><p>
不过我也没什么好办法了也许他们不重装我还想着试试SystemRescueCD试试看能不能把整个磁盘复制出来但是他们既然已经直接重装那就彻底没救了……QAQ</p>
<h1 id="亡羊补牢">
<a href="#亡羊补牢"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 亡羊补牢
</h1>
<p>既然数据已经救不回来了,那我们也只能向前看,得想办法避免以后再出现这样的问题。因为我最近在期末阶段,比较忙,所以也不经常去打快照。虽然以前也出现过服务出问题的情况,像<a href="/2020/01/05/devops.html">MySQL挂了</a>、CDN挂了、还有一次好像是交换机出问题了但是无论如何数据从来没有丢失过。这一次数据都能丢了也真的是太糟糕了要不是有快照那就真成删库跑路了…… </p><p>
既然没时间打快照,我得想个办法搞一个自动打快照的东西。在网上搜了搜,还真有这样的脚本,于是我拿来改了改就装上去用了。</p>
<h2 id="自动快照的脚本">
<a href="#自动快照的脚本"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 自动快照的脚本
</h2>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">requests</span>
<span class="kn">from</span> <span class="nn">requests</span> <span class="kn">import</span> <span class="n">get</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="k">class</span> <span class="nc">__RPC</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">api_key</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">api_key</span> <span class="o">=</span> <span class="n">api_key</span>
<span class="bp">self</span><span class="p">.</span><span class="n">api_info</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
<span class="bp">self</span><span class="p">.</span><span class="n">errors</span> <span class="o">=</span> <span class="p">{</span>
<span class="mi">200</span><span class="p">:</span> <span class="s">"Function successfully executed."</span><span class="p">,</span>
<span class="mi">400</span><span class="p">:</span> <span class="s">"Invalid API location. Check the URL that you are using."</span><span class="p">,</span>
<span class="mi">403</span><span class="p">:</span> <span class="s">"Invalid or missing API key. Check that your API key is present and matches your assigned key."</span><span class="p">,</span>
<span class="mi">405</span><span class="p">:</span> <span class="s">"Invalid HTTP method. Check that the method (POST|GET) matches what the documentation indicates."</span><span class="p">,</span>
<span class="mi">412</span><span class="p">:</span> <span class="s">"Request failed. Check the response body for a more detailed description."</span><span class="p">,</span>
<span class="mi">500</span><span class="p">:</span> <span class="s">"Internal server error. Try again at a later time."</span><span class="p">,</span>
<span class="mi">503</span><span class="p">:</span> <span class="s">"Rate limit hit. API requests are limited to an average of 2/s. Try your request again later."</span>
<span class="p">}</span>
<span class="k">def</span> <span class="nf">api_info_initial</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">api_info</span> <span class="o">=</span> <span class="p">{</span><span class="s">"snapshot/create"</span><span class="p">:</span><span class="s">"POST"</span><span class="p">,</span><span class="s">"snapshot/destroy"</span><span class="p">:</span><span class="s">"POST"</span><span class="p">,</span><span class="s">"snapshot/list"</span><span class="p">:</span><span class="s">"GET"</span><span class="p">,</span><span class="s">"server/list"</span><span class="p">:</span><span class="s">"GET"</span><span class="p">}</span>
<span class="k">def</span> <span class="nf">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">eval</span><span class="p">(</span><span class="s">"__RPC"</span><span class="p">)(</span><span class="bp">self</span><span class="p">.</span><span class="n">api_key</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">name</span> <span class="o">+</span> <span class="s">"/"</span> <span class="o">+</span> <span class="n">name</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="p">.</span><span class="n">api_info</span><span class="p">:</span>
<span class="bp">self</span><span class="p">.</span><span class="n">api_info_initial</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">.</span><span class="n">api_info</span><span class="p">:</span>
<span class="k">raise</span> <span class="nb">ValueError</span><span class="p">(</span><span class="s">"The API is not exists."</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">api_info</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">name</span><span class="p">]</span> <span class="o">==</span> <span class="s">"GET"</span><span class="p">:</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">"https://api.vultr.com/v1/"</span> <span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s">"API-Key"</span><span class="p">:</span> <span class="bp">self</span><span class="p">.</span><span class="n">api_key</span><span class="p">},</span>
<span class="n">params</span><span class="o">=</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">elif</span> <span class="bp">self</span><span class="p">.</span><span class="n">api_info</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">name</span><span class="p">]</span> <span class="o">==</span> <span class="s">"POST"</span><span class="p">:</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="s">"https://api.vultr.com/v1/"</span> <span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s">"API-Key"</span><span class="p">:</span> <span class="bp">self</span><span class="p">.</span><span class="n">api_key</span><span class="p">},</span> <span class="n">data</span><span class="o">=</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">if</span> <span class="n">res</span><span class="p">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">200</span><span class="p">:</span>
<span class="k">return</span> <span class="n">res</span><span class="p">.</span><span class="n">status_code</span><span class="p">,</span> <span class="n">res</span><span class="p">.</span><span class="n">text</span><span class="p">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">res</span><span class="p">.</span><span class="n">status_code</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">.</span><span class="n">errors</span><span class="p">.</span><span class="n">keys</span><span class="p">():</span>
<span class="k">return</span> <span class="n">res</span><span class="p">.</span><span class="n">status_code</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">errors</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">res</span><span class="p">.</span><span class="n">status_code</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">res</span><span class="p">.</span><span class="n">raise_for_status</span><span class="p">()</span>
<span class="k">class</span> <span class="nc">Vultr</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">api_key</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">api_key</span> <span class="o">=</span> <span class="n">api_key</span>
<span class="k">def</span> <span class="nf">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">eval</span><span class="p">(</span><span class="s">"__RPC"</span><span class="p">)(</span><span class="bp">self</span><span class="p">.</span><span class="n">api_key</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
<span class="n">vultr</span> <span class="o">=</span> <span class="n">Vultr</span><span class="p">(</span><span class="s">"API Key"</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s">'SUBID'</span><span class="p">:</span> <span class="s">'实例ID'</span><span class="p">}</span>
<span class="n">status_code</span><span class="p">,</span> <span class="n">resp</span> <span class="o">=</span> <span class="n">vultr</span><span class="p">.</span><span class="n">snapshot</span><span class="p">.</span><span class="n">create</span><span class="p">(</span><span class="o">**</span><span class="n">data</span><span class="p">)</span>
<span class="n">requests</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="s">"https://sc.ftqq.com/SCKEY.send"</span><span class="p">,</span><span class="n">data</span> <span class="o">=</span><span class="p">{</span><span class="s">"text"</span><span class="p">:</span><span class="s">"快照已创建"</span><span class="p">,</span><span class="s">"desp"</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">status_code</span><span class="p">)</span><span class="o">+</span><span class="n">resp</span><span class="p">})</span>
<span class="c1"># 删除旧快照
</span><span class="n">status_code</span><span class="p">,</span> <span class="n">resp</span> <span class="o">=</span> <span class="n">vultr</span><span class="p">.</span><span class="n">snapshot</span><span class="p">.</span><span class="nb">list</span><span class="p">()</span> <span class="c1"># /v1/snapshot/list
</span><span class="k">if</span> <span class="n">status_code</span> <span class="o">!=</span> <span class="mi">200</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="s">'获取快照列表失败'</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">status_code</span><span class="p">)</span> <span class="o">+</span> <span class="n">resp</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="s">'成功获取到快照列表'</span><span class="p">)</span>
<span class="n">data_list</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">json</span><span class="p">.</span><span class="n">loads</span><span class="p">(</span><span class="n">resp</span><span class="p">).</span><span class="n">values</span><span class="p">())</span>
<span class="n">data_list</span><span class="p">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="p">[</span><span class="s">'date_created'</span><span class="p">])</span> <span class="c1"># 默认时间排序,由近到远
</span> <span class="n">data_list_del</span> <span class="o">=</span> <span class="n">data_list</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="mi">9</span><span class="p">:]</span> <span class="c1"># 取超过9个之后的快照
</span> <span class="k">for</span> <span class="n">data_del</span> <span class="ow">in</span> <span class="n">data_list_del</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s">'SNAPSHOTID'</span><span class="p">:</span> <span class="n">data_del</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'SNAPSHOTID'</span><span class="p">)}</span>
<span class="n">status_code</span><span class="p">,</span> <span class="n">resp</span> <span class="o">=</span> <span class="n">vultr</span><span class="p">.</span><span class="n">snapshot</span><span class="p">.</span><span class="n">destroy</span><span class="p">(</span><span class="o">**</span><span class="n">data</span><span class="p">)</span> <span class="c1"># /v1/snapshot/destroy
</span> <span class="k">if</span> <span class="n">status_code</span> <span class="o">!=</span> <span class="mi">200</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="s">'删除旧快照失败'</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="s">'成功删除一个旧快照'</span><span class="p">)</span>
</code></pre></div></div>
<p>把这个脚本放到Crontab里每天执行一次就行了。</p>
<h1 id="后记">
<a href="#后记"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 后记
</h1>
<p>相信服务器厂商是完全靠不住的事情自己还得想办法做好备份。我甚至在想阿三把Intel和微软都占领了会不会有一个阿三也跑到Vultr里然后对着我的硬盘大喊“把你变成咖喱”之类的23333。 </p><p>
现在不过是权宜之计,以后还是得想办法把整个论坛下载到本地,至少能搞个数据库的差异备份啥的也行啊……</p></main>
<small style="display: block">tags: <a rel="category tag" class="p-category" href="/search.html?keyword=%E5%A4%87%E4%BB%BD"><em>备份</em></a> <span style="float: right;"><a href="https://gitlab.com/mayx/mayx.gitlab.io/tree/master/_posts/2020-06-17-backup.md">查看原始文件</a></span></small>
<h4 style="border-bottom: 1px solid #e5e5e5;margin: 2em 0 5px;">推荐文章</h4>
<p id="suggest-container">Loading...</p>
<script>
var suggest = $("#suggest-container");
$.get(BlogAPI + "/suggest?id=/2020/06/17/backup.html&update=" + lastUpdated.valueOf(), function (data) {
if (data.length) {
getSearchJSON(function (search) {
suggest.empty();
var searchMap = {};
for (var i = 0; i < search.length; i++) {
searchMap[search[i].url] = search[i];
}
var tooltip = $('<div class="content-tooltip"></div>').appendTo('body').hide();
for (var j = 0; j < data.length; j++) {
var item = searchMap[data[j].id];
if (item) {
var link = $('<a href="' + item.url + '">' + item.title + '</a>');
var contentPreview = item.content.substring(0, 100);
if (item.content.length > 100) {
contentPreview += "……";
}
link.hover(
function(e) {
tooltip.text($(this).data('content'))
.css({
top: e.pageY + 10,
left: e.pageX + 10
})
.show();
},
function() {
tooltip.hide();
}
).mousemove(function(e) {
tooltip.css({
top: e.pageY + 10,
left: e.pageX + 10
});
}).data('content', contentPreview);
suggest.append(link);
suggest.append(' - ' + item.date + '<br />');
}
}
});
} else {
suggest.html("暂无推荐文章……");
}
});
</script>
<br />
<div class="pagination">
<span class="prev">
<a href="/2020/06/13/encrypt.html">
上一篇加密传输Demo V2
</a>
</span>
<br />
<span class="next">
<a href="/2020/07/29/card.html">
下一篇如何制作一个PCB名片
</a>
</span>
</div>
<!--[if !IE]> -->
<link rel="stylesheet" href="/assets/css/gitalk.css">
<script src="/assets/js/gitalk.min.js"></script>
<div id="gitalk-container"></div>
<script>
var gitalk = new Gitalk({
clientID: '36557aec4c3cb04f7ac6',
clientSecret: 'ac32993299751cb5a9ba81cf2b171cca65879cdb',
repo: 'mabbs.github.io',
owner: 'Mabbs',
admin: ['Mabbs'],
id: '/2020/06/17/backup', // Ensure uniqueness and length less than 50
distractionFreeMode: false, // Facebook-like distraction free mode
proxy: "https://cors-anywhere.mayx.eu.org/?https://github.com/login/oauth/access_token"
})
gitalk.render('gitalk-container')
</script>
<!-- <![endif]-->
</section>
<!--[if !IE]> -->
<div id="landlord" style="left:5px;bottom:0px;">
<div class="message" style="opacity:0"></div>
<canvas id="live2d" width="500" height="560" class="live2d"></canvas>
<div class="live_talk_input_body">
<form id="live_talk_input_form">
<div class="live_talk_input_name_body" >
<input type="checkbox" id="load_this" />
<input type="hidden" id="post_id" value="/2020/06/17/backup.html" />
<label for="load_this">
<span style="font-size: 11px; color: #fff;">&#160;想问这篇文章</span>
</label>
</div>
<div class="live_talk_input_text_body">
<input name="talk" type="text" class="live_talk_talk white_input" id="AIuserText" autocomplete="off" placeholder="要和我聊什么呀?" />
<button type="submit" class="live_talk_send_btn" id="talk_send">发送</button>
</div>
</form>
</div>
<input name="live_talk" id="live_talk" value="1" type="hidden" />
<div class="live_ico_box" style="display:none;">
<div class="live_ico_item type_info" id="showInfoBtn"></div>
<div class="live_ico_item type_talk" id="showTalkBtn"></div>
<div class="live_ico_item type_music" id="musicButton"></div>
<div class="live_ico_item type_youdu" id="youduButton"></div>
<div class="live_ico_item type_quit" id="hideButton"></div>
<input name="live_statu_val" id="live_statu_val" value="0" type="hidden" />
<audio src="" style="display:none;" id="live2d_bgm" data-bgm="0" preload="none"></audio>
<input id="duType" value="douqilai" type="hidden" />
</div>
</div>
<div id="open_live2d">召唤伊斯特瓦尔</div>
<!-- <![endif]-->
<footer>
<p>
<small>Made with ❤ by Mayx<br />Last updated at 2026-01-01 00:00:18<br /> 总字数614622 - 文章数178 - <a href="/atom.xml" >Atom</a> - <a href="/README.html" >About</a></small>
</p>
</footer>
</div>
<script src="/assets/js/scale.fix.js"></script>
<!--[if !IE]> -->
<script src="/assets/js/main_new.js"></script>
<script src="/Live2dHistoire/live2d/js/live2d.js"></script>
<script src="/Live2dHistoire/live2d/js/message.js"></script>
<!-- <![endif]-->
</body>
</html>