If you ran my previous blog entry on exporting and importing users + role assignments via the TDTT (Test Data Transfer Tool) then in some cases where a custom role was created and assigned then the assignment may not show up in the UI. This is because the data is transferred but the root handle id has changed/is different from environment to environment. So we need to update the security role assignment with the correct root handle.
In order to fix this
issue we need to do the following
On the model db of the src and of the target
SELECT [RootHandle],[ElementHandle],[Name]
FROM
[dbo].[ModelElement]
where ElementType = '133'
order by name
(Element Type = 133 is telling us to display roles only)
Then we need to compare the root handle ids to one another for each of the
role names. If they do not match then the following needs to happen on the
target db (data database)
update [ax_target_db].[dbo].[SECURITYUSERROLE]
set SECURITYROLE
='roothandlefromtargetdb'
where SECURITYROLE = 'roothandlefromsrcdb'
After running this then your root handles for roles should match up now.
Thursday, August 27, 2015
Exporting/Importing specific tables via the TDTT (Test Data Transfer Tool) / Transfering only user tables with role assignments via TDTT
Recently after starting to use the Test Data Transfer Tool (TDTT) it was brought to my attention that users and role associations were not coming over. This is because by default this tool has a list of tables to not export. You can control which tables do and do not get exported/imported by modifying these lists. Currently you can find these lists within the install folder of the TDDT (dp.exe) If you choose the default install location it would be located at
C:\Program Files (x86)\Microsoft Dynamics AX 2012 Test Data Transfer Tool (Beta)\[Lists]
By default the tool will ignore any table names found within these txt files. However in our case we only want to export/import the specific user tables and nothing else. So first we need to look at how we can accomplish this.
To only include a specific table we can use the following code:
.*(?<!^Table1)
or if we only want to export 2 tables .*(?<!^Table1)(?<!^Table2)
This gives us the functionality to export/import specific tables. However now we need to figure out which tables we actually need to transfer in order to correctly transfer users + their role assignments.
We can start by looking at the default file "Exclude - User.txt" However this does not include the role assignments which you may also need. The role assignments are present at the table SECURITYUSERROLE. So combining the default list + the role table we get the following
.*(?<!^SYSBCPROXYUSERACCOUNT)(?<!^USERINFOSTARTUPMODEL)(?<!^SYSCOMPANYUSERINFO)(?<!^USERSIDCACHE)(?<!^(DEL_)?USERINFO)(?<!^(DEL_)?USERGROUPLIST)(?<!^(DEL_)?USERGROUPINFO)(?<!^SYSUSERPROFILES)(?<!^SYSUSERLOG)(?<!^SYSUSERINFO)(?<!^SYSUSER.*)(?<!^SECURITYUSERROLE)
Once we have the new file defined with the code above we need to remove all other lists from this folder so that it will only export/import the tables we have defined in our new file instead of exporting the entire db but excluding the tables defined by default. Whenever these files are removed and only 1 is left in the folder you issue the same command to export/import the entire db but this time it should only grab the tables defined in your new file.
Commands to export/import:
DP.exe export C:\AXExport src_db_name sql\AXInstance
DP.exe import C:\AXExport target_db_name sql\AXInstance
Per the TechNet article on the TDTT we can use the following regular expression syntax in our include/exclude lists
You can view the rest of the filtering options for this tool @ Run the Test Data Transfer Tool (beta) for Microsoft Dynamics AX [AX 2012]
C:\Program Files (x86)\Microsoft Dynamics AX 2012 Test Data Transfer Tool (Beta)\[Lists]
By default the tool will ignore any table names found within these txt files. However in our case we only want to export/import the specific user tables and nothing else. So first we need to look at how we can accomplish this.
To only include a specific table we can use the following code:
.*(?<!^Table1)
or if we only want to export 2 tables .*(?<!^Table1)(?<!^Table2)
This gives us the functionality to export/import specific tables. However now we need to figure out which tables we actually need to transfer in order to correctly transfer users + their role assignments.
We can start by looking at the default file "Exclude - User.txt" However this does not include the role assignments which you may also need. The role assignments are present at the table SECURITYUSERROLE. So combining the default list + the role table we get the following
.*(?<!^SYSBCPROXYUSERACCOUNT)(?<!^USERINFOSTARTUPMODEL)(?<!^SYSCOMPANYUSERINFO)(?<!^USERSIDCACHE)(?<!^(DEL_)?USERINFO)(?<!^(DEL_)?USERGROUPLIST)(?<!^(DEL_)?USERGROUPINFO)(?<!^SYSUSERPROFILES)(?<!^SYSUSERLOG)(?<!^SYSUSERINFO)(?<!^SYSUSER.*)(?<!^SECURITYUSERROLE)
Once we have the new file defined with the code above we need to remove all other lists from this folder so that it will only export/import the tables we have defined in our new file instead of exporting the entire db but excluding the tables defined by default. Whenever these files are removed and only 1 is left in the folder you issue the same command to export/import the entire db but this time it should only grab the tables defined in your new file.
Commands to export/import:
DP.exe export C:\AXExport src_db_name sql\AXInstance
DP.exe import C:\AXExport target_db_name sql\AXInstance
Per the TechNet article on the TDTT we can use the following regular expression syntax in our include/exclude lists
Regular expression syntax | Description |
---|---|
. | Match any single character. |
* | Match the previous expression zero or more times. |
(?<! subexpression) | Prevent a match if the end of the previously matched content matches the subexpression. This expression is known as a zero-width negative lookbehind assertion. |
^ | Match the start of the string. |
You can view the rest of the filtering options for this tool @ Run the Test Data Transfer Tool (beta) for Microsoft Dynamics AX [AX 2012]
The number of joins in the statement is 31. This exceeds the maximum of 26.
When modifying some base forms to include new tables you might get the error
The number of joins in the statement is 31. This exceeds the maximum of 26. Turn on exception for this warning to see the call stack.
In order to fix this we need to bump the max limit (default is 26.) We can do this by going to
System Administration > Setup > System > Server Configuration Then go to the Performance Optimization tab and change the field 'Maximum number of tables in join' After making this change you may need to restart the aos in order for the changes to take affect.
This setting fixes the error but before making this change you should take a look at what you are trying to accomplish with this many joins. Can we get rid of some of the tables? Have we split the data into to many tables? Can this be accomplished another way? While having a form with this many joins can cause performance issues sometimes its your only option as default AX may already hit that 24-26 join mark so you are left with no option but to uptick the amount of joins allowed.
The number of joins in the statement is 31. This exceeds the maximum of 26. Turn on exception for this warning to see the call stack.
In order to fix this we need to bump the max limit (default is 26.) We can do this by going to
System Administration > Setup > System > Server Configuration Then go to the Performance Optimization tab and change the field 'Maximum number of tables in join' After making this change you may need to restart the aos in order for the changes to take affect.
This setting fixes the error but before making this change you should take a look at what you are trying to accomplish with this many joins. Can we get rid of some of the tables? Have we split the data into to many tables? Can this be accomplished another way? While having a form with this many joins can cause performance issues sometimes its your only option as default AX may already hit that 24-26 join mark so you are left with no option but to uptick the amount of joins allowed.
Wednesday, August 19, 2015
How to copy data from one Microsoft Dynamics AX 2012 R2 AOS to another (MSSQL VS Test Data Transfer Tool (TDTT))
Below will show you the steps on how to copy all of the data from one aos to another.
Related: How to promote entire Microsoft Dynamics AX 2012 R2 Code Base (MSSQL VS AXUtil VS Powershell)
*Option 2 should be only used when promoting to
non-production environments
Related: How to promote entire Microsoft Dynamics AX 2012 R2 Code Base (MSSQL VS AXUtil VS Powershell)
Export Data
o
Option 1 (MSSQL Server):
§
Stop AOS
§
Make backup of database from within MSSQL
management studio
§
Be sure to compress the db! (via software
method)
§
Note: this option can cause issues with syncing
the db and you may need to manually drop tables and reimport the data
o
Option 2 (Test Data Transfer Tool):
§
Info: TechNet
§
Download: Available in Microsoft Lifecycle
Services > Downloadable tools
§
DP.exe <direction> <directory>
<database> <server>
·
Example: DP.exe export C:\AXExport AX_PROD_01 SQL\AXPROD
§
This should never be used to import data into
prod, only user it on environments such as qc, test, dev.
§
It also has the ability to skip certain tables
such as system settings. See the link above for more details on skipping tables
NOTE: This needs to be ran on the sql box where the db is located. It uses whatever account triggers dp.exe so that user needs to have access to the raw sql db as wellImport Data
o
Option 1 (MSSQL Server): Restore Database
§
Settings (General): Override old db name with
the db you want to restore to
§
Settings (Files): Change file name under
“restore as” to the db you want import to.
§
Settings (Options): Overwrite the existing
database (WITH REPLACE) should be checked
§
Start AOS
§
Run full compile via client side (long compile)
·
Since the DB is different it’s better to do this
on the client to make sure no errors exist
§
Sync Data Dictionary (makes sure table indexes
are good to go)
§
Full CIL
o
Option 2 (Test Data Transfer Tool):
§
DP.exe <direction> <directory>
<database> <server>
·
Example: DP.exe import C:\AXExport AX_PROD_01 SQL\AXPROD
NOTE: This needs to be ran on the sql box where the db is located. It uses whatever account triggers dp.exe so that user needs to have access to the raw sql db as well
NOTE: This needs to be ran on the sql box where the db is located. It uses whatever account triggers dp.exe so that user needs to have access to the raw sql db as well
Settings that need updated
· System administration/Setup
o
Batch Group
§
Remove servers from transferring dbs
§
Assign all groups to the correct batch server(s)
related to the current environment
o
System / Server configuration
§
Remove servers from transferring dbs
§
Mark batch servers related to the current
environment
o
System / Cluster configuration (Prod)
§
Doing the previous step should remove the
servers from the transferring dbs, but if it doesn’t remove it from here as
well.
§
Create group for batch server
·
Assign batch servers into this group via the
cluster name field on the grid
§
Create group for non-batch servers
·
Assign non-batch server into this group via the
cluster name field on the grid
o
System / E-mail Parameters
§
Local Computer Name – update to the current aos
§
Password: enter password for email
o
System / Help system parameters
§
Update URL according to the environment
§
Example: http://aoswebserver:8080/DynamicsAX6HelpServer/HelpService.svc
o
Business intelligence / Analysis Services /
Analysis Servers
§
OLAP servers (tab) > OLAP Server Name –
change to db\instance of current aos sql server
·
Example: sql\axprod
o
Business intelligence / Reporting Services /
Report servers
§
Create instance for every aos and update with
related SQL/SSRS information
§
Server Name: <sql server name>
·
When dealing with a cluster it seems to work
better to list the default ssrs box
§
Server instance name: <sql instance name>
§
Report Manager URL: http://aosssrs/Reports_AXPROD
§
Web service URL: http://aosssrs/ReportServer_AXPROD
§
Report Folder: DynamicsAX
§
AOS: point to the aos (this is the setting you
change for every aos when dealing with a cluster)
o
Enterprise Portal / Web sites
§
Change internal/external urls to AX Sharepoint
urls
·
Example: http://aoswebserver/sites/DynamicsAx
§
Type: Full
·
With importing data, there comes a risk that the
code may be expecting certain number sequences to be setup which are not. THIS IS OPTIONAL AND NOT REQUIRED ON
EVERY IMPORT
o
Because of this, run the Number Sequence Wizard
under Organization Administration \ Common \ Number Sequences \ Number
Sequences List page \ “Generate” under “New” on the Action Bar
o
That will generate any un-generated Number
sequences.
§
Take note of what it generates, and the Number
sequence code, as further tuning may be necessary because the sequences default
to Company-####, which may not be desired.
How to promote entire Microsoft Dynamics AX 2012 R2 Code Base (MSSQL VS AXUtil VS Powershell)
The following will walk you thru multiple ways to export and import a code base from one aos to another.
Microsoft recommends option 2 or 3. But option 2 utilizes powershell which Microsoft has been pushing so this is probably the best route.
All methods below goes under the assumption that a clean compile has just occurred on the source that you are exporting from.
Related: How to copy data from one Microsoft Dynamics AX 2012 R2 AOS to another (MSSQL VS Test Data Transfer Tool (TDTT))
Microsoft recommends option 2 or 3. But option 2 utilizes powershell which Microsoft has been pushing so this is probably the best route.
All methods below goes under the assumption that a clean compile has just occurred on the source that you are exporting from.
Related: How to copy data from one Microsoft Dynamics AX 2012 R2 AOS to another (MSSQL VS Test Data Transfer Tool (TDTT))
Export Code
o
Option 1 (MSSQL Server):
§
Stop AOS
§
Make backup of database from within MSSQL
management studio
§
Be sure to compress the db! (via software
method)
o
Option 2 (AOS Server): Microsoft Dynamics AX Management Shell
(Control Panel > Admin Tools)
§
Export-AXModel –Model <name> -File
<Filename.axmodel>
·
Example: Export-AXModel –Model “CUS Model” –File
Cus073115.axmodel
o
Option 3 (AOS Server): AXUtil
§
CMD.EXE > CD %ProgramFiles%\Microsoft Dynamics
AX\60\ManagementUtilities
§
CMD.EXE > axutil export /model:<Modelname>
/file:<filename> /verbose
·
Example: axutil export /model:”CUS Model”
/file:Cus073115
Import Code
o
Option 1 (MSSQL Server): Restore Database
§
Settings (General): Override old db name with
the db you want to restore to
§
Settings (Files): Change file name under
“restore as” to the db you want import to.
§
Settings (Options): Overwrite the existing
database (WITH REPLACE) should be checked
§
Start AOS
§
Run full compile via client side (long compile)
·
Since the DB is different it’s better to do this
on the client to make sure no errors exist
§
Sync Data Dictionary (makes sure table indexes
are good to go)
§
Full CIL
§
Deploy ALL reports
o
Option 2 (AOS Server): Microsoft Dynamics AX Management Shell
(Control Panel > Admin Tools)
§
Install-AXModel –File <Filename.axmodel>
-Details
·
Example: Install-AXModel –File Cus073115.axmodel
–Details
§
Sync Data Dictionary (makes sure table indexes
are good to go)
§
Full CIL
§
*It’s good to note that a full compile is not
necessary but it won’t hurt anything
§
You can run server side compile (quick)
·
CMD.EXE (As Admin) > cd C:\Program
Files\Microsoft Dynamics AX\60\Server\AX_TEST_01\bin
·
CMD.EXE > axbuild.exe xppcompileall
/s=01 /altbin="C:\Program Files (x86)\Microsoft Dynamics
AX\60\Client\Bin"
§
Deploy ALL reports
§
You may need to run the note at the bottom of
this list as well
§
To re-index the model if need be: axutil
optimize /config:ax_configuration_utility_instance_name
o
Option 3 (AOS Server): AXUtil
§
CMD.EXE > CD %ProgramFiles%\Microsoft Dynamics
AX\60\ManagementUtilities
§
CMD.EXE > axutil import
/file:<filename> /verbose
·
Exmple: axutil /file:Cus073115 /verbose
§
Sync Data Dictionary (makes sure table indexes
are good to go)
§
Full CIL
§
*It’s good to note that a full compile is not
necessary but it won’t hurt anything
§
You can run server side compile (quick)
·
CMD.EXE (As Admin) > cd C:\Program
Files\Microsoft Dynamics AX\60\Server\AX_TEST_01\bin
·
CMD.EXE > axbuild.exe xppcompileall
/s=01 /altbin="C:\Program Files (x86)\Microsoft Dynamics
AX\60\Client\Bin"
§
Deploy ALL reports
§
You may need to run the note at the bottom of
this list as well
§
To re-index the model if need be: axutil
optimize /config:ax_configuration_utility_instance_name
Note: You may need to do
the following if you have a clean code base but can’t get a clean cil
·
Stop all AOS instances
·
Delete all files on the AOS server under
C:\Program Files\Microsoft Dynamics AX\60\Server\<aos instance name>\bin\XppIL
·
Connect to the model db via SQL Management
studio
·
Truncate the table SYSXPPASSEMBLY which lists
all of the files found in step 2
·
You can do this via the command: TRUNCATE TABLE
SYSXPPASSEMBLY
·
Start 1 AOS instance if running under a cluster
·
Run Full CIL
·
Start remaining AOS instances
Wednesday, August 5, 2015
KB 2905338 - fix - Incorrect yields being applied when running price calculations for multiple parts at a time (2012 R2)
Recently we discovered a bug when running pricing calculations from Inventory and warehouse management/Setup/Costing/Costing Versions
it appeared that whenever you ran pricing from the item itself than it ran but whenever you ran it from the generic costing versions screen the yield was always 100%
We discovered that "KB 2905338, Bug Id 839225: When calculating price on the cost version form, AX ignores the batch size setup on formula version and uses the default order quantity instead" fixed our issue which is located at \Classes\BOMCalcJob.constructBOMCalcItem() because it added in the clause to populate the yield % from the current bomVersionitem. However this updates a new bug into the system.
Whenever you run a single item from the main costing versions form then the correct yields are pulled in. The moment you run it for multiple parts (at the same time, when its not wide open for an entire site) via Inv/Ware house Mgt >Costing Versions then it ever so slightly modifies your costing results incorrectly.
The issue is that when running pricing for multiple parts at a time it takes the first item's info and uses that as the "main item" for every part you run. Thus affecting your output. You only notice this issue whenever you run it for multiple parts at a time.
You can fix this by removing the piece of code in \Classes\BOMCalcJob.constructBOMCalcItem() this.parmPmfBOMVersion(bomVersionItem); Once this is removed it appears to still respect the hotfix and the fix to handle processing multiple specific items at a time.
The issue is caused by the if statement at the stop that checks to see if pmfBOMVersion.RecId has a value which it now does.
it appeared that whenever you ran pricing from the item itself than it ran but whenever you ran it from the generic costing versions screen the yield was always 100%
We discovered that "KB 2905338, Bug Id 839225: When calculating price on the cost version form, AX ignores the batch size setup on formula version and uses the default order quantity instead" fixed our issue which is located at \Classes\BOMCalcJob.constructBOMCalcItem() because it added in the clause to populate the yield % from the current bomVersionitem. However this updates a new bug into the system.
Whenever you run a single item from the main costing versions form then the correct yields are pulled in. The moment you run it for multiple parts (at the same time, when its not wide open for an entire site) via Inv/Ware house Mgt >Costing Versions then it ever so slightly modifies your costing results incorrectly.
The issue is that when running pricing for multiple parts at a time it takes the first item's info and uses that as the "main item" for every part you run. Thus affecting your output. You only notice this issue whenever you run it for multiple parts at a time.
You can fix this by removing the piece of code in \Classes\BOMCalcJob.constructBOMCalcItem() this.parmPmfBOMVersion(bomVersionItem); Once this is removed it appears to still respect the hotfix and the fix to handle processing multiple specific items at a time.
The issue is caused by the if statement at the stop that checks to see if pmfBOMVersion.RecId has a value which it now does.
Monday, August 3, 2015
Get largest tables (by size in pages/mb) in use by AX (2012 R2)
Recently we saw a huge growth on our database overnight and started to get curious what caused it. By using the query below we were table to track it to a specific table thus tracking it to a specific feature within AX. The following query will show you the largest tables in your database for AX which can then help you track down what might need to do be done.
*Note: this should be ran under a query within your data-side database for AX.
SELECT
tables.NAME AS TableName,
indexes.name as IndexName,
sum(partitions.rows) as NumberOfRows,
sum(allocation_units.total_pages) as TotalPages,
sum(allocation_units.used_pages) as UsedPages,
sum(allocation_units.data_pages) as DataPages,
(sum(allocation_units.total_pages) * 8) / 1024 as TotalSizeMB,
(sum(allocation_units.used_pages) * 8) / 1024 as UsedSizeMB,
(sum(allocation_units.data_pages) * 8) / 1024 as DataSizeMB
FROM
sys.tables
INNER JOIN
sys.indexes ON tables.OBJECT_ID = indexes.object_id
INNER JOIN
sys.partitions ON indexes.object_id = partitions.OBJECT_ID AND indexes.index_id = partitions.index_id
INNER JOIN
sys.allocation_units ON partitions.partition_id = allocation_units.container_id
GROUP BY
tables.NAME, indexes.object_id, indexes.index_id, indexes.name
ORDER BY
TotalSizeMB DESC
*Note: this should be ran under a query within your data-side database for AX.
SELECT
tables.NAME AS TableName,
indexes.name as IndexName,
sum(partitions.rows) as NumberOfRows,
sum(allocation_units.total_pages) as TotalPages,
sum(allocation_units.used_pages) as UsedPages,
sum(allocation_units.data_pages) as DataPages,
(sum(allocation_units.total_pages) * 8) / 1024 as TotalSizeMB,
(sum(allocation_units.used_pages) * 8) / 1024 as UsedSizeMB,
(sum(allocation_units.data_pages) * 8) / 1024 as DataSizeMB
FROM
sys.tables
INNER JOIN
sys.indexes ON tables.OBJECT_ID = indexes.object_id
INNER JOIN
sys.partitions ON indexes.object_id = partitions.OBJECT_ID AND indexes.index_id = partitions.index_id
INNER JOIN
sys.allocation_units ON partitions.partition_id = allocation_units.container_id
GROUP BY
tables.NAME, indexes.object_id, indexes.index_id, indexes.name
ORDER BY
TotalSizeMB DESC
Subscribe to:
Posts (Atom)