-
-
Notifications
You must be signed in to change notification settings - Fork 110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
XtraBackup source - Does not produce 1 file #9
Comments
Hi, i ran into this problem with the Maybe the All the informations that has to be transfared from the
Or can you think of something else? |
I think those are all good ideas! For #10, we will need to be able to tell the target to not create the target folder. That is because if we create the folder, say For #10, we will need to be able to signal to the If you could get these changes in, I can then submit my PRs for a few different sources 😄 |
Just an update on this one. I have completed sources for ArangoDB and XtraBackup. The only blockers left for those 2 sources are the issues highlighted here:
|
I have thought a lot about that problem. I'm having a hard time to make a final decision. 1. Let the
|
I have 2 ideas:
|
I like your Nr. 2, I thought about extending the What Do you think about the following: Adding two methods to the Source interface
So the Runner/Target could decide if and how to compress the generated data. if (!$source->isHandlingCompression()) {
$this->handleCompression($target, $source->getSourceData());
} Add an abstract base abstract class CompressionHandler
{
public function isHandlingCompression()
{
return true;
}
public function getSourceData()
{
throw new Exception('source is handling compression by itself');
}
} Big Pro Pro Con Con |
Good idea! However, I am not too sure about having How do you feel about having a general method that returns a configuration object? If we need to add more configuration in the future, we can just add things to the configuration object. |
I see your point. But this is hiding implementation details you have to be aware of if you create your own The general variant you are suggesting could look something like this. Status class (pure dummy) class Status
{
public function __construct($isCompressed = true, array $dataPath = array())
{
$this->isCompressed = $isCompressed;
$this->dataPath = $dataPath;
}
// ... setter/getter methods ...
} Source base class abstract class CompressionHandler
{
public function getStatus()
{
return new Status(true);
}
} Runner logic $source->backup($target, $result);
$status = $source->getStatus();
if (!$status->isCompressed()) {
$this->handleCompression($target, $status->getDataPath());
} This looks like some kind of detour to me. |
I was thinking maybe something like this: Base source class abstract class Source{
public function getSourceConfig(){
//This should return default config, so that only "special" sources need to implement this method
return new SourceConfig(array('doNotCreateDirectories' => true, 'isCompressed' => true));
//Flaw: cannot enforce return type as SourceConfig, but we can check this in Runner until PHP 7 lands.
}
abstract public function setup(array $conf = array());
abstract public function backup(Target $target, Result $result);
} SourceConfig class class SourceConfig{
public function __construct(array $conf){
//convert config array and do things with it
}
} Runner $config = $source->getConfig(); //Get the config to use with the factories later.
$target = TargetFactory($config);
//Other factories also has access to $config so that the source can provide some configuration (if required)
//Here, the target factory looks at the config and sees "doNotCreateDirectories == true" and does not create directories.
//Target factory can also see if the source needs a file or directory target and returns `FileTarget` or `DirectoryTarget` targets |
We are dealing with two problems at the same time. Lets split this up. 1 The directory problemI think this should be handled within the source by just adding a subdirectory to the public function backup(Target $target, Result $result)
{
// use some none existing sub directory or any other location you like
$dumpDir = $target->getPath() . '/dumpDir'; 2 The compression no compressionInstead of using a new method to get the Interface Source
{
/**
* @return \phpbu\App\Backup\Source\Status
*/
public function backup(Target $target, Result $result);
} public function backup(Target $target, Result $result)
{
$dumpDir = $target->getPath() . '/dumpDir';
// ...
return new Status(false, $dumpDir); So $status = $source->backup($target, $result);
if (!$status->isCompressed()) {
$this->handleCompression($target, $status->getDataPath());
} I think this is the best solution so far. |
That looks great! I really like how you handled the compression problem. I think that's how the second issue should be implemented 😄 However, I still have a question regarding the directory problem. For example, if the user uses this config: <target dirname="/backup/mysql/data-%Y%m%d-%H%i"/> We would then ask We can have the source ask The issue of having a folder instead of 1 file is also a bit trouble some. Let's say the tool is able to dump the files into |
Ok Nr 2. solved! Great! If you look at the So i think both, directory and filename should be configured. <target dirname="/backup/mysql/data-%Y%m%d-%H%i" filename="innox.dump" compress="bzip2"/> The It's only getting complicated if for some reason you want to keep the original uncompressed files. Later we could add some methods to the <option name="keepOriginalDumpDir" value="true"/> The problem with keeping the dump dirs is, the |
Good idea! What if there is no |
Maybe <xs:attribute name="dirname" use="required" type="xs:string"/>
<xs:attribute name="filename" use="required" type="xs:string"/> it already is, but the I think if no |
But if the user does not want to compress the backup, then the filename would be extraneous (and perhaps a bit confusing) wouldn't it? |
Yes it would be. This one is on me, I haven't thought of the possibility to keep unkompressed folders :( |
Yes that sounds good. I think we should keep it simple for now, because I would love to send some PRs for my other sources 😄 If you could get that implemented, I can then rebase and get my PRs in 😄 |
Awesome! |
I saw some commits. Is this feature considered done? |
Not quiet jet. |
Awesome! 😄 |
'Runner' is able to handle uncompressed source data
I just pushed the changes. If you have a look at the return Status::create()->uncompressed()->dataPath($this->getDumpDir($target)); The After integrating your new sources I think I have to refactor quite a bit. I don't like the inheritance But first things first ;) |
I also added some Exceptions to the |
Is the generated tar suppose to have a Currently, when I run my dump, it creates a tar file with the following inside:
I do not have monogodb installed, so I cannot tell if mongodb also has the same behaviour. |
Currently I call the tar command with "." at the end, so there are no leading directories included in the archive. |
Ah, I see. The command being called is So, that's why everything will be placed under a directory called |
I am currently implementing an XtraBackup source which uses Percona's XtraBackup tool to perform backups for mysql.
The problem is that XtraBackup will dump a bunch of files into a folder rather than producing 1 file such as
backup.sql
. I have already implemented the source and it works properly.The only problem is if
compress
andencrypt
is enabled on the target, it will break because those methods expect a file and not a folder of files.1 solution is to have the XtraBackup source tar the files, but I feel the source is probably doing a bit too much.
Let me know what you think.
I also plan to implement a few more sources which will produce dumps that are a bunch of files instead of 1 file.
The text was updated successfully, but these errors were encountered: